Module: ActiveRecordCustomPreloader::WithMultipleForeignKeysLoading
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/active_record_custom_preloader/with_multiple_foreign_keys_loading.rb
Instance Method Summary collapse
-
#association_foreign_keys(assoc_record) ⇒ Object
association records are grouped by return value of this method.
-
#associations_by_record(grouped_associations, parent_record) ⇒ Object
returns associations for provided parent_record.
-
#associations_scope ⇒ Object
default scope for association records.
- #fetch_association(parent_records) ⇒ Object
- #preload(parent_records) ⇒ Object
-
#record_foreign_keys(parent_record) ⇒ Object
association table is queried by return value of this method.
Instance Method Details
#association_foreign_keys(assoc_record) ⇒ Object
association records are grouped by return value of this method. it should match returns array of keys for association record to match parent record
57 58 59 |
# File 'lib/active_record_custom_preloader/with_multiple_foreign_keys_loading.rb', line 57 def association_foreign_keys(assoc_record) association_foreign_keys_names.map { |name| assoc_record.public_send(name) } end |
#associations_by_record(grouped_associations, parent_record) ⇒ Object
returns associations for provided parent_record. array for has_many and model or nil for has_one.
63 64 65 66 |
# File 'lib/active_record_custom_preloader/with_multiple_foreign_keys_loading.rb', line 63 def associations_by_record(grouped_associations, parent_record) associations = grouped_associations[record_foreign_keys(parent_record)] to_many ? associations || [] : associations&.first end |
#associations_scope ⇒ Object
default scope for association records. you can override it for example to preload some values to association records.
70 71 72 |
# File 'lib/active_record_custom_preloader/with_multiple_foreign_keys_loading.rb', line 70 def associations_scope model_class_name.constantize.all end |
#fetch_association(parent_records) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/active_record_custom_preloader/with_multiple_foreign_keys_loading.rb', line 74 def fetch_association(parent_records) keys = parent_records.map(&method(:record_foreign_keys)).compact condition_part = association_foreign_keys_names.map { |name| "#{name} = ?" }.join(' AND ') conditions = [] keys.size.times { conditions.push(condition_part) } condition_sql = conditions.map { |condition| "(#{condition})" }.join(' OR ') condition_bindings = keys.flatten return {} if condition_sql.blank? || condition_bindings.empty? associations = associations_scope.where(condition_sql, *condition_bindings).to_a associations.group_by(&method(:association_foreign_keys)) end |
#preload(parent_records) ⇒ Object
86 87 88 89 90 91 92 |
# File 'lib/active_record_custom_preloader/with_multiple_foreign_keys_loading.rb', line 86 def preload(parent_records) grouped_associations = fetch_association(parent_records) parent_records.each do |parent_record| value = associations_by_record(grouped_associations, parent_record) parent_record._set_custom_preloaded_value(name, value) end end |
#record_foreign_keys(parent_record) ⇒ Object
association table is queried by return value of this method. returns array of keys for parent record to match association record. if you want to skip association for particular record - return nil.
50 51 52 |
# File 'lib/active_record_custom_preloader/with_multiple_foreign_keys_loading.rb', line 50 def record_foreign_keys(parent_record) association_foreign_keys(parent_record) end |