2011-03-31 00:31:39 +00:00
|
|
|
module Ransack
|
|
|
|
module Nodes
|
|
|
|
class Grouping < Node
|
|
|
|
attr_reader :conditions
|
2011-06-05 18:29:54 +00:00
|
|
|
attr_accessor :combinator
|
|
|
|
alias :m :combinator
|
|
|
|
alias :m= :combinator=
|
|
|
|
|
2011-03-31 00:31:39 +00:00
|
|
|
i18n_word :condition, :and, :or
|
|
|
|
i18n_alias :c => :condition, :n => :and, :o => :or
|
|
|
|
|
2014-05-01 13:55:39 +00:00
|
|
|
delegate :each, :to => :values
|
2011-03-31 00:31:39 +00:00
|
|
|
|
2011-06-05 18:29:54 +00:00
|
|
|
def initialize(context, combinator = nil)
|
|
|
|
super(context)
|
|
|
|
self.combinator = combinator.to_s if combinator
|
|
|
|
end
|
|
|
|
|
2011-03-31 00:31:39 +00:00
|
|
|
def persisted?
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
def translate(key, options = {})
|
2014-05-01 13:55:39 +00:00
|
|
|
super or Translate.attribute(
|
|
|
|
key.to_s, options.merge(:context => context)
|
|
|
|
)
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def conditions
|
|
|
|
@conditions ||= []
|
|
|
|
end
|
|
|
|
alias :c :conditions
|
|
|
|
|
|
|
|
def conditions=(conditions)
|
|
|
|
case conditions
|
|
|
|
when Array
|
|
|
|
conditions.each do |attrs|
|
|
|
|
condition = Condition.new(@context).build(attrs)
|
|
|
|
self.conditions << condition if condition.valid?
|
|
|
|
end
|
|
|
|
when Hash
|
|
|
|
conditions.each do |index, attrs|
|
|
|
|
condition = Condition.new(@context).build(attrs)
|
|
|
|
self.conditions << condition if condition.valid?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
self.conditions.uniq!
|
|
|
|
end
|
|
|
|
alias :c= :conditions=
|
|
|
|
|
|
|
|
def [](key)
|
2013-08-12 08:27:50 +00:00
|
|
|
if condition = conditions.detect { |c| c.key == key.to_s }
|
2011-03-31 00:31:39 +00:00
|
|
|
condition
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def []=(key, value)
|
2013-08-12 08:27:50 +00:00
|
|
|
conditions.reject! { |c| c.key == key.to_s }
|
2011-03-31 00:31:39 +00:00
|
|
|
self.conditions << value
|
|
|
|
end
|
|
|
|
|
|
|
|
def values
|
2011-06-05 18:29:54 +00:00
|
|
|
conditions + groupings
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def respond_to?(method_id)
|
|
|
|
super or begin
|
|
|
|
method_name = method_id.to_s
|
|
|
|
writer = method_name.sub!(/\=$/, '')
|
|
|
|
attribute_method?(method_name) ? true : false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def build_condition(opts = {})
|
|
|
|
new_condition(opts).tap do |condition|
|
|
|
|
self.conditions << condition
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def new_condition(opts = {})
|
|
|
|
attrs = opts[:attributes] || 1
|
|
|
|
vals = opts[:values] || 1
|
|
|
|
condition = Condition.new(@context)
|
|
|
|
attrs.times { condition.build_attribute }
|
|
|
|
vals.times { condition.build_value }
|
|
|
|
condition
|
|
|
|
end
|
|
|
|
|
2011-06-05 18:29:54 +00:00
|
|
|
def groupings
|
|
|
|
@groupings ||= []
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
2011-06-05 18:29:54 +00:00
|
|
|
alias :g :groupings
|
2011-03-31 00:31:39 +00:00
|
|
|
|
2011-06-05 18:29:54 +00:00
|
|
|
def groupings=(groupings)
|
|
|
|
case groupings
|
2011-03-31 00:31:39 +00:00
|
|
|
when Array
|
2011-06-05 18:29:54 +00:00
|
|
|
groupings.each do |attrs|
|
|
|
|
grouping_object = new_grouping(attrs)
|
|
|
|
self.groupings << grouping_object if grouping_object.values.any?
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
when Hash
|
2011-06-05 18:29:54 +00:00
|
|
|
groupings.each do |index, attrs|
|
|
|
|
grouping_object = new_grouping(attrs)
|
|
|
|
self.groupings << grouping_object if grouping_object.values.any?
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
else
|
2013-08-12 08:27:50 +00:00
|
|
|
raise ArgumentError,
|
|
|
|
"Invalid argument (#{groupings.class}) supplied to groupings="
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
end
|
2011-06-05 18:29:54 +00:00
|
|
|
alias :g= :groupings=
|
2011-03-31 00:31:39 +00:00
|
|
|
|
|
|
|
def method_missing(method_id, *args)
|
|
|
|
method_name = method_id.to_s
|
|
|
|
writer = method_name.sub!(/\=$/, '')
|
|
|
|
if attribute_method?(method_name)
|
2013-12-10 18:17:21 +00:00
|
|
|
writer ?
|
|
|
|
write_attribute(method_name, *args) :
|
|
|
|
read_attribute(method_name)
|
2011-03-31 00:31:39 +00:00
|
|
|
else
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def attribute_method?(name)
|
|
|
|
name = strip_predicate_and_index(name)
|
|
|
|
case name
|
2011-06-05 18:29:54 +00:00
|
|
|
when /^(g|c|m|groupings|conditions|combinator)=?$/
|
2011-03-31 00:31:39 +00:00
|
|
|
true
|
|
|
|
else
|
2013-12-09 10:05:10 +00:00
|
|
|
name.split(/_and_|_or_/)
|
|
|
|
.select { |n| !@context.attribute_method?(n) }
|
|
|
|
.empty?
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-06-05 18:29:54 +00:00
|
|
|
def build_grouping(params = {})
|
2011-03-31 00:31:39 +00:00
|
|
|
params ||= {}
|
2011-06-05 18:29:54 +00:00
|
|
|
new_grouping(params).tap do |new_grouping|
|
|
|
|
self.groupings << new_grouping
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-06-05 18:29:54 +00:00
|
|
|
def new_grouping(params = {})
|
|
|
|
Grouping.new(@context).build(params)
|
2011-03-31 00:31:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def build(params)
|
|
|
|
params.with_indifferent_access.each do |key, value|
|
|
|
|
case key
|
2011-06-05 18:29:54 +00:00
|
|
|
when /^(g|c|m)$/
|
2011-03-31 00:31:39 +00:00
|
|
|
self.send("#{key}=", value)
|
|
|
|
else
|
|
|
|
write_attribute(key.to_s, value)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2012-08-07 15:07:42 +00:00
|
|
|
def inspect
|
2014-05-01 13:55:39 +00:00
|
|
|
data = [['conditions', conditions], ['combinator', combinator]]
|
|
|
|
.reject { |e| e[1].blank? }
|
2013-12-10 18:17:21 +00:00
|
|
|
.map { |v| "#{v[0]}: #{v[1]}" }
|
|
|
|
.join(', ')
|
2012-08-07 15:07:42 +00:00
|
|
|
"Grouping <#{data}>"
|
|
|
|
end
|
|
|
|
|
2011-03-31 00:31:39 +00:00
|
|
|
private
|
|
|
|
|
|
|
|
def write_attribute(name, val)
|
|
|
|
# TODO: Methods
|
|
|
|
if condition = Condition.extract(@context, name, val)
|
|
|
|
self[name] = condition
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def read_attribute(name)
|
|
|
|
if self[name].respond_to?(:value)
|
|
|
|
self[name].value
|
|
|
|
else
|
|
|
|
self[name]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def strip_predicate_and_index(str)
|
|
|
|
string = str.split(/\(/).first
|
2011-06-07 01:32:03 +00:00
|
|
|
Predicate.detect_and_strip_from_string!(string)
|
2011-03-31 00:31:39 +00:00
|
|
|
string
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2013-12-10 09:57:26 +00:00
|
|
|
end
|