2011-03-31 00:31:39 +00:00
|
|
|
require 'ransack/nodes'
|
|
|
|
require 'ransack/context'
|
|
|
|
require 'ransack/naming'
|
|
|
|
|
|
|
|
module Ransack
|
|
|
|
class Search
|
|
|
|
include Naming
|
|
|
|
|
|
|
|
attr_reader :base, :context
|
|
|
|
|
2013-08-12 08:27:50 +00:00
|
|
|
delegate :object, :klass, to: :context
|
2011-06-05 18:29:54 +00:00
|
|
|
delegate :new_grouping, :new_condition,
|
|
|
|
:build_grouping, :build_condition,
|
2013-08-12 08:27:50 +00:00
|
|
|
:translate, to: :base
|
2011-03-31 00:31:39 +00:00
|
|
|
|
2011-04-12 00:07:23 +00:00
|
|
|
def initialize(object, params = {}, options = {})
|
2013-08-16 19:04:37 +00:00
|
|
|
(params ||= {}).delete_if { |k, v| v.blank? && v != false }
|
2011-09-03 19:37:02 +00:00
|
|
|
@context = Context.for(object, options)
|
2011-04-12 00:07:23 +00:00
|
|
|
@context.auth_object = options[:auth_object]
|
2011-06-05 18:29:54 +00:00
|
|
|
@base = Nodes::Grouping.new(@context, 'and')
|
2011-03-31 00:31:39 +00:00
|
|
|
build(params.with_indifferent_access)
|
|
|
|
end
|
|
|
|
|
|
|
|
def result(opts = {})
|
2011-04-14 00:15:57 +00:00
|
|
|
@context.evaluate(self, opts)
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def build(params)
|
|
|
|
collapse_multiparameter_attributes!(params).each do |key, value|
|
|
|
|
case key
|
|
|
|
when 's', 'sorts'
|
|
|
|
send("#{key}=", value)
|
|
|
|
else
|
|
|
|
base.send("#{key}=", value) if base.attribute_method?(key)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
|
|
|
def sorts=(args)
|
|
|
|
case args
|
|
|
|
when Array
|
|
|
|
args.each do |sort|
|
|
|
|
sort = Nodes::Sort.extract(@context, sort)
|
|
|
|
self.sorts << sort
|
|
|
|
end
|
|
|
|
when Hash
|
|
|
|
args.each do |index, attrs|
|
|
|
|
sort = Nodes::Sort.new(@context).build(attrs)
|
|
|
|
self.sorts << sort
|
|
|
|
end
|
2011-08-13 20:36:40 +00:00
|
|
|
when String
|
2011-03-31 00:31:39 +00:00
|
|
|
self.sorts = [args]
|
2011-08-13 20:36:40 +00:00
|
|
|
else
|
|
|
|
raise ArgumentError, "Invalid argument (#{args.class}) supplied to sorts="
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
alias :s= :sorts=
|
|
|
|
|
|
|
|
def sorts
|
|
|
|
@sorts ||= []
|
|
|
|
end
|
|
|
|
alias :s :sorts
|
|
|
|
|
|
|
|
def build_sort(opts = {})
|
|
|
|
new_sort(opts).tap do |sort|
|
|
|
|
self.sorts << sort
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def new_sort(opts = {})
|
|
|
|
Nodes::Sort.new(@context).build(opts)
|
|
|
|
end
|
|
|
|
|
|
|
|
def method_missing(method_id, *args)
|
|
|
|
method_name = method_id.to_s
|
|
|
|
writer = method_name.sub!(/\=$/, '')
|
|
|
|
if base.attribute_method?(method_name)
|
|
|
|
base.send(method_id, *args)
|
|
|
|
else
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-08-07 15:07:42 +00:00
|
|
|
def inspect
|
|
|
|
"Ransack::Search<class: #{klass.name}, base: #{base.inspect}>"
|
|
|
|
end
|
|
|
|
|
2011-03-31 00:31:39 +00:00
|
|
|
private
|
|
|
|
|
|
|
|
def collapse_multiparameter_attributes!(attrs)
|
|
|
|
attrs.keys.each do |k|
|
|
|
|
if k.include?("(")
|
|
|
|
real_attribute, position = k.split(/\(|\)/)
|
|
|
|
cast = %w(a s i).include?(position.last) ? position.last : nil
|
|
|
|
position = position.to_i - 1
|
|
|
|
value = attrs.delete(k)
|
|
|
|
attrs[real_attribute] ||= []
|
|
|
|
attrs[real_attribute][position] = if cast
|
|
|
|
(value.blank? && cast == 'i') ? nil : value.send("to_#{cast}")
|
|
|
|
else
|
|
|
|
value
|
|
|
|
end
|
|
|
|
elsif Hash === attrs[k]
|
|
|
|
collapse_multiparameter_attributes!(attrs[k])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
attrs
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
2012-10-11 12:43:40 +00:00
|
|
|
end
|