Module | Sequel::Plugins::DatasetAssociations::DatasetMethods |
In: |
lib/sequel/plugins/dataset_associations.rb
|
For the association given by name, return a dataset of associated objects such that it would return the union of calling the association method on all objects returned by the current dataset.
This supports most options that are supported when eager loading. However, it will only work for limited associations or *_one associations with orders if the database supports window functions.
# File lib/sequel/plugins/dataset_associations.rb, line 70 70: def associated(name) 71: raise Error, "unrecognized association name: #{name.inspect}" unless r = model.association_reflection(name) 72: ds = r.associated_class.dataset 73: sds = opts[:limit] ? self : unordered 74: ds = case r[:type] 75: when :many_to_one 76: ds.filter(r.qualified_primary_key=>sds.select(*Array(r[:qualified_key]))) 77: when :one_to_one, :one_to_many 78: r.send(:apply_filter_by_associations_limit_strategy, ds.filter(r.qualified_key=>sds.select(*Array(r.qualified_primary_key)))) 79: when :many_to_many, :one_through_one 80: mds = r.associated_class.dataset. 81: join(r[:join_table], r[:right_keys].zip(r.right_primary_keys)). 82: select(*Array(r.qualified_right_key)). 83: where(r.qualify(r.join_table_alias, r[:left_keys])=>sds.select(*r.qualify(model.table_name, r[:left_primary_key_columns]))) 84: ds.filter(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds)) 85: when :many_through_many, :one_through_many 86: fre = r.reverse_edges.first 87: fe, *edges = r.edges 88: edges << r.final_edge 89: mds = model. 90: select(*Array(r.qualify(fre[:table], fre[:left]))). 91: join(fe[:table], Array(fe[:right]).zip(Array(fe[:left])), :implicit_qualifier=>model.table_name). 92: where(r.qualify(fe[:table], fe[:right])=>sds.select(*r.qualify(model.table_name, r[:left_primary_key_columns]))) 93: edges.each{|e| mds = mds.join(e[:table], Array(e[:right]).zip(Array(e[:left])))} 94: ds.filter(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds)) 95: when :pg_array_to_many 96: ds.filter(Sequel.expr(r.primary_key=>sds.select{Sequel.pg_array_op(r.qualify(r[:model].table_name, r[:key])).unnest})) 97: when :many_to_pg_array 98: ds.filter(Sequel.function(:coalesce, Sequel.pg_array_op(r[:key]).overlaps(sds.select{array_agg(r.qualify(r[:model].table_name, r.primary_key))}), false)) 99: else 100: raise Error, "unrecognized association type for association #{name.inspect}: #{r[:type].inspect}" 101: end 102: r.apply_eager_dataset_changes(ds).unlimited 103: end