lib/sakuramochi/predicate_builder.rb in sakuramochi-0.5.8 vs lib/sakuramochi/predicate_builder.rb in sakuramochi-0.5.9
- old
+ new
@@ -6,41 +6,35 @@
extend ActiveSupport::Concern
included do
unless respond_to? :build
def self.build(attribute, value)
- model_class = defined?(ActiveRecord::Model) ? ActiveRecord::Model : ActiveRecord::Base
-
case value
when ActiveRecord::Relation
value = value.select(value.klass.arel_table[value.klass.primary_key]) if value.select_values.empty?
attribute.in(value.arel.ast)
when Array, ActiveRecord::Associations::CollectionProxy
- values = value.to_a.map {|x| x.is_a?(model_class) ? x.id : x}
- ranges, values = values.partition {|v| v.is_a?(Range)}
+ values = value.to_a.map {|x| x.is_a?(ActiveRecord::Base) ? x.id : x}
+ ranges, values = values.partition {|v| v.is_a?(Range) || v.is_a?(Arel::Relation)}
- values_predicate = if values.include?(nil)
- values = values.compact
+ array_predicates = ranges.map {|range| attribute.in(range)}
- case values.length
- when 0
- attribute.eq(nil)
- when 1
- attribute.eq(values.first).or(attribute.eq(nil))
+ if values.include?(nil)
+ values = values.compact
+ if values.empty?
+ array_predicates << attribute.eq(nil)
else
- attribute.in(values).or(attribute.eq(nil))
+ array_predicates << attribute.in(values.compact).or(attribute.eq(nil))
end
else
- attribute.in(values)
+ array_predicates << attribute.in(values)
end
- array_predicates = ranges.map { |range| attribute.in(range) }
- array_predicates << values_predicate
- array_predicates.inject { |composite, predicate| composite.or(predicate) }
- when Range
+ array_predicates.inject {|composite, predicate| composite.or(predicate)}
+ when Range, Arel::Relation
attribute.in(value)
- when model_class
+ when ActiveRecord::Base
attribute.eq(value.id)
when Class
# FIXME: I think we need to deprecate this behavior
attribute.eq(value.name)
else
@@ -54,21 +48,26 @@
alias :build_from_hash :build_from_hash_with_predicate
end
end
module ClassMethods
- def build_from_hash_with_predicate(engine, attributes, default_table)
- attributes.map do |column, value|
+ def build_from_hash_with_predicate(engine, attributes, default_table, allow_table_name = true)
+ predicates = attributes.map do |column, value|
table = default_table
- if value.is_a?(Hash)
+ if allow_table_name && value.is_a?(Hash)
table = Arel::Table.new(column, engine)
- build_from_hash_with_predicate(engine, value, table)
+
+ if value.empty?
+ '1 = 2'
+ else
+ build_from_hash_with_predicate(engine, value, table, false)
+ end
else
column = column.to_s
- if column.include?('.')
+ if allow_table_name && column.include?('.')
table_name, column = column.split('.', 2)
table = Arel::Table.new(table_name, engine)
end
column_name, predicate = Sakuramochi::Predicate.detect(column.to_s)
@@ -78,10 +77,12 @@
build_with_predicate(attribute, value, predicate)
else
build(attribute, value)
end
end
- end.flatten
+ end
+
+ predicates.flatten
end
private
def build_with_predicate(attribute, value, predicate)