lib/scoped_from/query.rb in scoped_from-0.7.0 vs lib/scoped_from/query.rb in scoped_from-0.8.0

- old
+ new

@@ -8,13 +8,13 @@ attr_reader :params # Available options are: - :only : to restrict to specified keys. # - :except : to ignore specified keys. - def initialize(scope, params, options = {}) - @scope = scope.scoped - @options = options + def initialize(relation, params, options = {}) + self.relation = relation + self.options = options self.params = params end def order_column parse_order(params['order'])[:column] @@ -22,38 +22,56 @@ def order_direction parse_order(params['order'])[:direction] end - def scope - scope = @scope + def relation + relation = @relation params.each do |name, value| [value].flatten.each do |value| - scope = scoped(scope, name, value) + relation = invoke_param(relation, name, value) end end - decorate_scope(scope) + decorate_relation(relation) end protected - def decorate_scope(scope) - return scope if scope.respond_to?(:query) - def scope.query + def decorate_relation(relation) + return relation if relation.respond_to?(:query) + def relation.query @__query end - scope.instance_variable_set('@__query', self) - scope + relation.instance_variable_set('@__query', self) + relation end + def invoke_param(relation, name, value) + if name.to_s == 'order' + relation.order(order_to_hash(value)) + elsif relation.scope_with_one_argument?(name) + relation.send(name, value) + elsif relation.scope_without_argument?(name) + relation.send(name) + elsif relation.column_names.include?(name.to_s) + relation.where(name => value) + else + relation + end + end + def false?(value) FALSE_VALUES.include?(value.to_s.strip.downcase) end - def order_to_sql(value) + def options=(options) + @options = options.symbolize_keys + end + + def order_to_hash(value) order = parse_order(value) - "#{order[:column]} #{order[:direction].upcase}" if order.present? + order.present? ? { order[:column] => order[:direction].downcase.to_sym } : {} end def params=(params) params = params.params if params.is_a?(self.class) params = CGI.parse(params.to_s) unless params.is_a?(Hash) @@ -62,17 +80,17 @@ values = [value].flatten next if values.empty? if name.to_s == 'order' orders = parse_orders(values).map { |order| "#{order[:column]}.#{order[:direction]}" } @params[name] = (orders.many? ? orders : orders.first) if orders.any? - elsif @scope.scope_without_argument?(name) + elsif @relation.scope_without_argument?(name) @params[name] = true if values.all? { |value| true?(value) } - elsif @scope.scope_with_one_argument?(name) + elsif @relation.scope_with_one_argument?(name) value = values.many? ? values : values.first @params[name] = @params[name] ? [@params[name], value].flatten : value - elsif @options[:exclude_columns].blank? && @scope.column_names.include?(name.to_s) - if @scope.columns_hash[name.to_s].type == :boolean + elsif @options[:exclude_columns].blank? && @relation.column_names.include?(name.to_s) + if @relation.columns_hash[name.to_s].type == :boolean @params[name] = true if values.all? { |value| true?(value) } @params[name] = false if values.all? { |value| false?(value) } else value = values.many? ? values : values.first @params[name] = @params[name] ? [@params[name], value].flatten : value @@ -85,33 +103,23 @@ def parse_order(value) column, direction = value.to_s.split(/[\.:\s]+/, 2) direction = direction.to_s.downcase direction = ORDER_DIRECTIONS.first unless ORDER_DIRECTIONS.include?(direction) - @scope.column_names.include?(column) ? { column: column, direction: direction } : {} + @relation.column_names.include?(column) ? { column: column, direction: direction } : {} end def parse_orders(values) [].tap do |orders| - values.each do |value| + values.reverse.each do |value| order = parse_order(value) orders << order if order.present? && !orders.any? { |o| o[:column] == order[:column] } end end end - def scoped(scope, name, value) - if name.to_s == 'order' - scope.order(order_to_sql(value)) - elsif scope.scope_with_one_argument?(name) - scope.send(name, value) - elsif scope.scope_without_argument?(name) - scope.send(name) - elsif scope.column_names.include?(name.to_s) - scope.scoped(conditions: { name => value }) - else - scope - end + def relation=(relation) + @relation = relation.is_a?(Class) ? relation.all : relation end def true?(value) TRUE_VALUES.include?(value.to_s.strip.downcase) end \ No newline at end of file