Class: RailsStackview::DbWindowFetcher
- Inherits:
-
Object
- Object
- RailsStackview::DbWindowFetcher
- Defined in:
- app/fetch_adapters/rails_stackview/db_window_fetcher.rb
Overview
Fetches from the stackview_call_numbers table with ActiveRecord
-
Assumes a windowing ‘search_type:loc_sort_order` in stackview, which sends query=[X TO Y] in params.
-
Additionally assumes we get an ‘origin_sort_key` in params, which will used as the “zero point” for stackview’s query ranges. It must be an actual normalized sort_key – if it does not exist in the DB, we’ll just browse from that point in sort order though.
We use this origin_sortkey to try and avoid very deep offsets in our SQL, which get expensive, although if the user pages a LOT they can still get there. If this is not good enough, we’ll have to contribute features to stackview to provide alternate windowing based on sortkeys alone.
Create a path to the StackviewDataController using 'lc' call_number_type,
which uses this fetcher, specifying the origin_sort_key as a query param:
stackview_data_path("lc", :origin_sort_key => some_sort_key)
Instance Method Summary collapse
- #fetch(params) ⇒ Object
-
#fetch_records(first, last) ⇒ Object
Returns ActiveRecord StackviewCallNumber objects.
- #negative_fetch(first, last) ⇒ Object
- #positive_fetch(first, last) ⇒ Object
Instance Method Details
#fetch(params) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'app/fetch_adapters/rails_stackview/db_window_fetcher.rb', line 25 def fetch(params) @origin_sort_key = params["origin_sort_key"] @sort_key_type = params["sort_key_type"] || "lc" unless @origin_sort_key.present? raise ArgumentError, "`origin_sort_key` param required, specifying where to start the browse" end (first, last) = RailsStackview.parse_query_range(params["query"]) unless first < last raise ArgumentError, "beginning of range must be less than end: #{params["query"]}" end # Fetch the AR models, then turn em into hashes, which include all # columns in the db, excluding some we don't want. # # Plus we need to turn our single creator into an array, cause # that's what stackview wants. results = fetch_records(first, last).collect do |record| record.attributes.except('id').reject {|k, v| v.blank? }. merge("creator" => (record["creator"].present? ? [record['creator']] : record['creator'])) end # Mark the thing at 0 index as origin:true, so it can be auto-selected # by browser. if (first..last).cover?(0) origin_index = [first.abs, results.length - 1].min results[origin_index]["is_origin_item"] = true end return results end |
#fetch_records(first, last) ⇒ Object
Returns ActiveRecord StackviewCallNumber objects.
61 62 63 64 65 66 67 68 69 70 |
# File 'app/fetch_adapters/rails_stackview/db_window_fetcher.rb', line 61 def fetch_records(first, last) if first >= 0 && last >= 0 # all positive positive_fetch(first, last) elsif first < 0 && last >= 0# cross zero-boundary # have to do half first and half last negative_fetch(first, -1) + positive_fetch(0, last) else # all negative negative_fetch(first, last) end end |
#negative_fetch(first, last) ⇒ Object
79 80 81 82 83 84 85 |
# File 'app/fetch_adapters/rails_stackview/db_window_fetcher.rb', line 79 def negative_fetch(first, last) StackviewCallNumber.where("sort_key < ?", @origin_sort_key). where(:sort_key_type => @sort_key_type). order("sort_key DESC"). offset(last.abs - 1).limit(last - first + 1). reverse end |
#positive_fetch(first, last) ⇒ Object
72 73 74 75 76 77 |
# File 'app/fetch_adapters/rails_stackview/db_window_fetcher.rb', line 72 def positive_fetch(first, last) StackviewCallNumber.where("sort_key >= ?", @origin_sort_key). where(:sort_key_type => @sort_key_type). order("sort_key ASC"). offset(first).limit(last - first + 1) end |