diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2016-02-18 10:47:47 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2016-02-18 10:47:47 -0800 |
commit | fb8d01f1ef7da0a3c8c0173d6c3da59afe9d1ca5 (patch) | |
tree | 258d75655ddcd9aacd2df0b74bb6c58404e3de9b /activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb | |
parent | e4c3225b2c9475ebfac474c7196dec2feb290e5a (diff) | |
parent | 3bd9fe1708018e4e82f5d836cc6e047d9d9b5b55 (diff) | |
download | rails-fb8d01f1ef7da0a3c8c0173d6c3da59afe9d1ca5.tar.gz rails-fb8d01f1ef7da0a3c8c0173d6c3da59afe9d1ca5.tar.bz2 rails-fb8d01f1ef7da0a3c8c0173d6c3da59afe9d1ca5.zip |
Merge branch 'master' into treewip
* master: (27 commits)
move digest cache on to the DetailsKey object
remove object `hash` cache
[ci skip] fix suggested change-replace 'an' with 'the in Rails engine guide'
Missing documentation about hash algorithm option for MessageVerifier [ci skip]
set `skip_listen` option to dummy appplication
Fix the language in engines guide
Add accidentally removed `#` [ci skip]
fields_for_style needs to test for AC::Parameters
Fix indentation for code block in changelog
Remove accidentally duplicated change log title [ci skip]
partially revert 69009f4473637a44ade26d954ef5ddea6ff903f2
Remove needless `case_insensitive_comparison` in mysql2 adapter
modify to `error` also abort when specify fail fast option
Implement ActionController::Parameters#inspect
remove unused method
Remove unused Journey code
Add Action Cable CHANGELOG in release notes [ci skip]
Show proper error message when a non-relation object is passed to AR::Relation#or
Fix semantics of test names for finish option in batches_test
Fix typo
...
Conflicts:
actionview/lib/action_view/digestor.rb
Diffstat (limited to 'activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb')
-rw-r--r-- | activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb new file mode 100644 index 0000000000..b6c6240343 --- /dev/null +++ b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb @@ -0,0 +1,57 @@ +module ActiveRecord + class PredicateBuilder + class PolymorphicArrayHandler # :nodoc: + def initialize(predicate_builder) + @predicate_builder = predicate_builder + end + + def call(attribute, value) + table = value.associated_table + queries = value.type_to_ids_mapping.map do |type, ids| + { table.association_foreign_type.to_s => type, table.association_foreign_key.to_s => ids } + end + + predicates = queries.map { |query| predicate_builder.build_from_hash(query) } + + if predicates.size > 1 + type_and_ids_predicates = predicates.map { |type_predicate, id_predicate| Arel::Nodes::Grouping.new(type_predicate.and(id_predicate)) } + type_and_ids_predicates.inject(&:or) + else + predicates.first + end + end + + protected + + attr_reader :predicate_builder + end + + class PolymorphicArrayValue # :nodoc: + attr_reader :associated_table, :values + + def initialize(associated_table, values) + @associated_table = associated_table + @values = values + end + + def type_to_ids_mapping + default_hash = Hash.new { |hsh, key| hsh[key] = [] } + values.each_with_object(default_hash) { |value, hash| hash[base_class(value).name] << convert_to_id(value) } + end + + private + + def primary_key(value) + associated_table.association_primary_key(base_class(value)) + end + + def base_class(value) + value.class.base_class + end + + def convert_to_id(value) + value._read_attribute(primary_key(value)) + end + end + end +end |