Module: LcpRuby::Widgets::ScopeApplicator
- Included in:
- DataResolver, PresenterZoneResolver, RecordSourceResolver
- Defined in:
- lib/lcp_ruby/widgets/scope_applicator.rb
Class Method Summary collapse
- .apply_date_range_filter(scope, model_class, field, value) ⇒ Object
-
.apply_filter_form(scope, model_class, filter_form) ⇒ Object
Applies a ‘Pages::FilterForm` to an AR scope.
-
.apply_scope_filters(scope, model_class, scope_filter_set) ⇒ Object
Applies a ‘Pages::ScopeFilterSet` to an AR scope.
- .apply_value_filter(scope, model_class, field, value) ⇒ Object
- .blank_filter_value?(value) ⇒ Boolean
- .dispatch_filter_value(scope, model_class, vfield, value) ⇒ Object
-
.resolve_filter_value(filter_form, vfield) ⇒ Object
Range inputs (‘date_range`, future `numeric_range`) decompose into paired `_from`/`_to` synthetic attributes on VirtualForm (see VirtualField#attribute_names).
Class Method Details
.apply_date_range_filter(scope, model_class, field, value) ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/lcp_ruby/widgets/scope_applicator.rb', line 168 def apply_date_range_filter(scope, model_class, field, value) return scope unless value.is_a?(Hash) return scope unless model_class.column_names.include?(field.to_s) from_date = value["from"] || value[:from] to_date = value["to"] || value[:to] if from_date && to_date scope.where(field => from_date..to_date) elsif from_date scope.where(model_class.arel_table[field].gteq(from_date)) elsif to_date scope.where(model_class.arel_table[field].lteq(to_date)) else scope end end |
.apply_filter_form(scope, model_class, filter_form) ⇒ Object
Applies a ‘Pages::FilterForm` to an AR scope. Reads typed AM::Attributes from the synthetic VirtualForm instance. Used by the dashboard + index-composite controllers. Spec § 5 step 13.
Dispatch by input_type:
* association_select / select / multi_select →
`where(field => value)` if column exists, else
`filter_<field>(scope, value)` host hook if defined.
* date_range → from/to via `arel_table[field].gteq/lteq`.
* Empty arrays are no-ops (never `WHERE field IN ()`).
92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/lcp_ruby/widgets/scope_applicator.rb', line 92 def apply_filter_form(scope, model_class, filter_form) return scope unless filter_form&.any? filter_form.each_field do |vfield| value = resolve_filter_value(filter_form, vfield) next if blank_filter_value?(value) scope = dispatch_filter_value(scope, model_class, vfield, value) end scope end |
.apply_scope_filters(scope, model_class, scope_filter_set) ⇒ Object
Applies a ‘Pages::ScopeFilterSet` to an AR scope. For each declared scope_filter the selected value is a scope name; if the model class responds_to the scope, dispatch via public_send. ScopeFilterSet’s enumerator already filtered out attacker values, so we trust the input here.
128 129 130 131 132 133 134 135 136 137 |
# File 'lib/lcp_ruby/widgets/scope_applicator.rb', line 128 def apply_scope_filters(scope, model_class, scope_filter_set) return scope unless scope_filter_set&.any? scope_filter_set.each do |_name, scope_key, _definition| next if scope_key.blank? scope = scope.public_send(scope_key) if model_class.respond_to?(scope_key) end scope end |
.apply_value_filter(scope, model_class, field, value) ⇒ Object
157 158 159 160 161 162 163 164 165 |
# File 'lib/lcp_ruby/widgets/scope_applicator.rb', line 157 def apply_value_filter(scope, model_class, field, value) if model_class.column_names.include?(field.to_s) scope.where(field => value) elsif model_class.respond_to?("filter_#{field}") model_class.public_send("filter_#{field}", scope, value) else scope end end |
.blank_filter_value?(value) ⇒ Boolean
140 141 142 143 144 |
# File 'lib/lcp_ruby/widgets/scope_applicator.rb', line 140 def blank_filter_value?(value) return true if value.nil? return true if value.respond_to?(:empty?) && value.empty? false end |
.dispatch_filter_value(scope, model_class, vfield, value) ⇒ Object
147 148 149 150 151 152 153 154 |
# File 'lib/lcp_ruby/widgets/scope_applicator.rb', line 147 def dispatch_filter_value(scope, model_class, vfield, value) case vfield.input_type when "date_range" apply_date_range_filter(scope, model_class, vfield.name, value) else apply_value_filter(scope, model_class, vfield.name, value) end end |
.resolve_filter_value(filter_form, vfield) ⇒ Object
Range inputs (‘date_range`, future `numeric_range`) decompose into paired `_from`/`_to` synthetic attributes on VirtualForm (see VirtualField#attribute_names). Build the `to:` Hash the dispatch path expects from those two attributes, instead of reading a single attribute named after the field.
111 112 113 114 115 116 117 118 119 120 |
# File 'lib/lcp_ruby/widgets/scope_applicator.rb', line 111 def resolve_filter_value(filter_form, vfield) if vfield.input_type == "date_range" from = filter_form.attributes["#{vfield.name}_from"] to = filter_form.attributes["#{vfield.name}_to"] return nil if from.blank? && to.blank? { "from" => from, "to" => to } else filter_form.attributes[vfield.name] end end |