Class: S2P::Search
- Inherits:
-
Object
- Object
- S2P::Search
- Includes:
- ActiveModel::Validations
- Defined in:
- lib/s2p/search.rb
Class Attribute Summary collapse
-
.from ⇒ Object
readonly
Returns the value of attribute from.
Instance Attribute Summary collapse
-
#conditions ⇒ Object
readonly
Returns the value of attribute conditions.
-
#params ⇒ Object
readonly
Returns the value of attribute params.
-
#results ⇒ Object
readonly
Returns the value of attribute results.
-
#scopes ⇒ Object
readonly
Returns the value of attribute scopes.
Class Method Summary collapse
- .additional_search_params(*keys) ⇒ Object
- .cond(key, &scope) ⇒ Object
- .cond_cont(*keys) ⇒ Object
- .cond_eq(*keys) ⇒ Object
- .cond_eq!(key, column) ⇒ Object
- .cond_gt(*keys) ⇒ Object
- .cond_gte(*keys) ⇒ Object
- .cond_gte!(key, column) ⇒ Object
- .cond_like(*keys) ⇒ Object
- .cond_like!(key, column) ⇒ Object
- .cond_localized_date_range(*ranges) ⇒ Object
-
.cond_localized_date_range!(start_key, end_key, column) ⇒ Object
NOTE: You can use cond_range instead of this method when working with date columns in the DB as they’re zoneless.
- .cond_lt(*keys) ⇒ Object
- .cond_lte(*keys) ⇒ Object
- .cond_lte!(key, column) ⇒ Object
- .cond_range(*ranges) ⇒ Object
- .cond_range!(start_key, end_key, column) ⇒ Object
- .cond_start(*keys) ⇒ Object
- .cond_start!(key, column) ⇒ Object
- .conditions ⇒ Object
- .create(params = {}) ⇒ Object
- .default_sort_order(params) ⇒ Object
- .scope ⇒ Object
- .search_keys ⇒ Object
- .searches(from) ⇒ Object
- .setup(&conds) ⇒ Object
- .sort_by_default(key) ⇒ Object
- .sort_by_default_key ⇒ Object
-
.sort_by_filters ⇒ Object
FIXME: Consider introducing a SortFilter object of some sort?.
- .sort_order_defaults ⇒ Object
- .sortable_by(*names, table_name: self.from.table_name) ⇒ Object
- .sortable_by!(name, asc:, desc:) ⇒ Object
- .sortable_by_alias(sort_alias, sort_condition) ⇒ Object
Instance Method Summary collapse
-
#initialize(params = {}) ⇒ Search
constructor
A new instance of Search.
- #save ⇒ Object
- #sorted(relation) ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(params = {}) ⇒ Search
Returns a new instance of Search.
196 197 198 199 200 201 202 203 204 205 |
# File 'lib/s2p/search.rb', line 196 def initialize(params={}) @params = params.symbolize_keys @conditions = self.class.conditions.select { |k,v| @params[k].present? } @sort_by_key = @params.fetch(:order_by, self.class.sort_by_default_key).to_sym @sort_order = @params.fetch(:sort_order, self.class.sort_order_defaults[@sort_by_key]).to_sym # FIXME: Should this be a validation instead? setup(**params) if respond_to?(:setup) end |
Class Attribute Details
.from ⇒ Object (readonly)
Returns the value of attribute from.
191 192 193 |
# File 'lib/s2p/search.rb', line 191 def from @from end |
Instance Attribute Details
#conditions ⇒ Object (readonly)
Returns the value of attribute conditions.
194 195 196 |
# File 'lib/s2p/search.rb', line 194 def conditions @conditions end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
194 195 196 |
# File 'lib/s2p/search.rb', line 194 def params @params end |
#results ⇒ Object (readonly)
Returns the value of attribute results.
194 195 196 |
# File 'lib/s2p/search.rb', line 194 def results @results end |
#scopes ⇒ Object (readonly)
Returns the value of attribute scopes.
194 195 196 |
# File 'lib/s2p/search.rb', line 194 def scopes @scopes end |
Class Method Details
.additional_search_params(*keys) ⇒ Object
18 19 20 |
# File 'lib/s2p/search.rb', line 18 def additional_search_params(*keys) @additional_search_params = keys end |
.cond(key, &scope) ⇒ Object
89 90 91 |
# File 'lib/s2p/search.rb', line 89 def cond(key, &scope) conditions[key] = scope end |
.cond_cont(*keys) ⇒ Object
170 171 172 173 174 |
# File 'lib/s2p/search.rb', line 170 def cond_cont(*keys) keys.each do |key| cond(key) { |s,v| s.where("#{from.table_name}.#{key} like ?", "%#{v}%") } end end |
.cond_eq(*keys) ⇒ Object
97 98 99 100 101 |
# File 'lib/s2p/search.rb', line 97 def cond_eq(*keys) keys.each do |key| cond_eq!(key, key) end end |
.cond_eq!(key, column) ⇒ Object
103 104 105 |
# File 'lib/s2p/search.rb', line 103 def cond_eq!(key, column) cond(key) { |s,v| s.where(column => v) } end |
.cond_gt(*keys) ⇒ Object
153 154 155 156 157 |
# File 'lib/s2p/search.rb', line 153 def cond_gt(*keys) keys.each do |key| cond(key) { |s,v| s.where("#{from.table_name}.#{key} > ?", v) } end end |
.cond_gte(*keys) ⇒ Object
143 144 145 146 147 |
# File 'lib/s2p/search.rb', line 143 def cond_gte(*keys) keys.each do |key| cond_gte!(key, "#{from.table_name}.#{key}") end end |
.cond_gte!(key, column) ⇒ Object
149 150 151 |
# File 'lib/s2p/search.rb', line 149 def cond_gte!(key, column) cond(key) { |s,v| s.where("#{column} >= ?", v) } end |
.cond_like(*keys) ⇒ Object
117 118 119 120 121 |
# File 'lib/s2p/search.rb', line 117 def cond_like(*keys) keys.each do |key| cond_like!(key, "#{from.table_name}.#{key}") end end |
.cond_like!(key, column) ⇒ Object
123 124 125 |
# File 'lib/s2p/search.rb', line 123 def cond_like!(key, column) cond(key) { |s,v| s.where("#{column} like ?", "%#{v}%") } end |
.cond_localized_date_range(*ranges) ⇒ Object
176 177 178 179 180 |
# File 'lib/s2p/search.rb', line 176 def cond_localized_date_range(*ranges) ranges.each do |range| cond_localized_date_range!(*range) end end |
.cond_localized_date_range!(start_key, end_key, column) ⇒ Object
NOTE: You can use cond_range instead of this method when working with date columns in the DB as they’re zoneless. This method is only necessary when working with datetime fields, because for those you will need to translate the beginning/end of the range to the localized beginning/end of day times.
186 187 188 189 |
# File 'lib/s2p/search.rb', line 186 def cond_localized_date_range!(start_key, end_key, column) cond(start_key) { |s,v| s.where("#{from.table_name}.#{column} >= ?", PetersenToolbox.to_local_time(Date.parse(v)).beginning_of_day) } cond(end_key) { |s,v| s.where("#{from.table_name}.#{column} <= ?", PetersenToolbox.to_local_time(Date.parse(v)).end_of_day) } end |
.cond_lt(*keys) ⇒ Object
127 128 129 130 131 |
# File 'lib/s2p/search.rb', line 127 def cond_lt(*keys) keys.each do |key| cond(key) { |s,v| s.where("#{from.table_name}.#{key} < ?", v) } end end |
.cond_lte(*keys) ⇒ Object
133 134 135 136 137 |
# File 'lib/s2p/search.rb', line 133 def cond_lte(*keys) keys.each do |key| cond_lte!(key, "#{from.table_name}.#{key}") end end |
.cond_lte!(key, column) ⇒ Object
139 140 141 |
# File 'lib/s2p/search.rb', line 139 def cond_lte!(key, column) cond(key) { |s,v| s.where("#{column} <= ?", v) } end |
.cond_range(*ranges) ⇒ Object
159 160 161 162 163 |
# File 'lib/s2p/search.rb', line 159 def cond_range(*ranges) ranges.each do |start_key, end_key, column| cond_range!(start_key, end_key, column) end end |
.cond_range!(start_key, end_key, column) ⇒ Object
165 166 167 168 |
# File 'lib/s2p/search.rb', line 165 def cond_range!(start_key, end_key, column) cond_gte!(start_key, column) cond_lte!(end_key, column) end |
.cond_start(*keys) ⇒ Object
107 108 109 110 111 |
# File 'lib/s2p/search.rb', line 107 def cond_start(*keys) keys.each do |key| cond_start!(key, "#{from.table_name}.#{key}") end end |
.cond_start!(key, column) ⇒ Object
113 114 115 |
# File 'lib/s2p/search.rb', line 113 def cond_start!(key, column) cond(key) { |s,v| s.where("#{column} like ?", "#{v}%") } end |
.conditions ⇒ Object
93 94 95 |
# File 'lib/s2p/search.rb', line 93 def conditions @conditions ||= {} end |
.create(params = {}) ⇒ Object
22 23 24 |
# File 'lib/s2p/search.rb', line 22 def create(params={}) new(params).tap(&:save) end |
.default_sort_order(params) ⇒ Object
81 82 83 |
# File 'lib/s2p/search.rb', line 81 def default_sort_order(params) sort_order_defaults.update(params).symbolize_keys! end |
.scope ⇒ Object
10 11 12 |
# File 'lib/s2p/search.rb', line 10 def scope @before_callback.present? ? @before_callback[from] : from end |
.search_keys ⇒ Object
14 15 16 |
# File 'lib/s2p/search.rb', line 14 def search_keys [:page, :sort_order, :order_by] + conditions.keys + (@additional_search_params || []) end |
.searches(from) ⇒ Object
26 27 28 |
# File 'lib/s2p/search.rb', line 26 def searches(from) @from ||= from end |
.setup(&conds) ⇒ Object
6 7 8 |
# File 'lib/s2p/search.rb', line 6 def setup(&conds) @before_callback = conds end |
.sort_by_default(key) ⇒ Object
73 74 75 |
# File 'lib/s2p/search.rb', line 73 def sort_by_default(key) @sort_by_default_key = key end |
.sort_by_default_key ⇒ Object
77 78 79 |
# File 'lib/s2p/search.rb', line 77 def sort_by_default_key @sort_by_default_key || :id end |
.sort_by_filters ⇒ Object
FIXME: Consider introducing a SortFilter object of some sort?
65 66 67 68 69 70 71 |
# File 'lib/s2p/search.rb', line 65 def sort_by_filters @sort_by_filters ||= Hash.new { |h,k| h[k] = {} } @sort_by_filters[:id][:asc] ||= ->(s) { s.reorder(id: :asc) } @sort_by_filters[:id][:desc] ||= ->(s) { s.reorder(id: :desc) } @sort_by_filters end |
.sort_order_defaults ⇒ Object
85 86 87 |
# File 'lib/s2p/search.rb', line 85 def sort_order_defaults @sort_order_defaults ||= Hash.new { |h,k| h[k] = :asc } end |
.sortable_by(*names, table_name: self.from.table_name) ⇒ Object
30 31 32 33 34 35 36 37 |
# File 'lib/s2p/search.rb', line 30 def sortable_by(*names, table_name: self.from.table_name) names.each do |name| sortable_by!(name, asc: ->(s) { s.reorder("#{table_name}.#{name} asc") }, desc: ->(s) { s.reorder("#{table_name}.#{name} desc") } ) end end |
.sortable_by!(name, asc:, desc:) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/s2p/search.rb', line 46 def sortable_by!(name, asc:, desc:) name = name.to_sym case asc when String sort_by_filters[name][:asc] = ->(s) { s.reorder(asc) } when Proc sort_by_filters[name][:asc] = asc end case desc when String sort_by_filters[name][:desc] = ->(s) { s.reorder(desc) } when Proc sort_by_filters[name][:desc] = desc end end |
.sortable_by_alias(sort_alias, sort_condition) ⇒ Object
39 40 41 42 43 44 |
# File 'lib/s2p/search.rb', line 39 def sortable_by_alias(sort_alias, sort_condition) sortable_by!(sort_alias, asc: ->(s) { s.reorder("#{sort_condition} asc") }, desc: ->(s) { s.reorder("#{sort_condition} desc") } ) end |
Instance Method Details
#save ⇒ Object
207 208 209 210 211 212 213 214 215 |
# File 'lib/s2p/search.rb', line 207 def save if valid? @results = @conditions.inject(self.class.scope) { |relation, (key, scope)| scope.call(relation, @params[key], @params) } @results = sorted(@results) end end |
#sorted(relation) ⇒ Object
217 218 219 |
# File 'lib/s2p/search.rb', line 217 def sorted(relation) self.class.sort_by_filters[@sort_by_key][@sort_order][relation] end |
#to_s ⇒ Object
221 222 223 |
# File 'lib/s2p/search.rb', line 221 def to_s @params.select { |k,v| v.present? }.map { |k,v| "<strong>#{k.to_s.humanize}</strong>: #{v}" }.join(" + ") end |