class Sequel::Model::Associations::ManyToManyAssociationReflection
Constants
- FINALIZE_SETTINGS
Public Instance Methods
The alias to use for the associated key when eagerly loading
# File lib/sequel/model/associations.rb, line 1223 def associated_key_alias self[:left_key_alias] end
Array of associated keys used when eagerly loading.
# File lib/sequel/model/associations.rb, line 1228 def associated_key_array cached_fetch(:associated_key_array) do if self[:uses_left_composite_keys] associated_key_alias.zip(predicate_keys).map{|a, k| SQL::AliasedExpression.new(k, a)} else [SQL::AliasedExpression.new(predicate_key, associated_key_alias)] end end end
The column to use for the associated key when eagerly loading
# File lib/sequel/model/associations.rb, line 1239 def associated_key_column self[:left_key] end
Alias of #right_primary_keys
# File lib/sequel/model/associations.rb, line 1244 def associated_object_keys right_primary_keys end
many_to_many associations can only have associated objects if none of the :left_primary_keys options have a nil value.
# File lib/sequel/model/associations.rb, line 1250 def can_have_associated_objects?(obj) !self[:left_primary_keys].any?{|k| obj.get_column_value(k).nil?} end
one_through_one and many_to_many associations can be clones
# File lib/sequel/model/associations.rb, line 1255 def cloneable?(ref) ref[:type] == :many_to_many || ref[:type] == :one_through_one end
The default associated key alias(es) to use when eager loading associations via eager.
# File lib/sequel/model/associations.rb, line 1261 def default_associated_key_alias self[:uses_left_composite_keys] ? (0...self[:left_keys].length).map{|i| :"x_foreign_key_#{i}_x"} : :x_foreign_key_x end
The default eager loader used if the user doesn't override it. Extracted to a method so the code can be shared with the many_through_many plugin.
# File lib/sequel/model/associations.rb, line 1267 def default_eager_loader(eo) h = eo[:id_map] assign_singular = assign_singular? delete_rn = delete_row_number_column uses_lcks = self[:uses_left_composite_keys] left_key_alias = self[:left_key_alias] name = self[:name] self[:model].eager_load_results(self, eo) do |assoc_record| assoc_record.values.delete(delete_rn) if delete_rn hash_key = if uses_lcks left_key_alias.map{|k| assoc_record.values.delete(k)} else assoc_record.values.delete(left_key_alias) end objects = h[hash_key] if assign_singular objects.each do |object| object.associations[name] ||= assoc_record end else objects.each do |object| object.associations[name].push(assoc_record) end end end end
Default name symbol for the join table.
# File lib/sequel/model/associations.rb, line 1298 def default_join_table [self[:class_name], self[:model].name].map{|i| underscore(pluralize(demodulize(i)))}.sort.join('_').to_sym end
Default foreign key name symbol for key in join table that points to current table's primary key (or :left_primary_key column).
# File lib/sequel/model/associations.rb, line 1304 def default_left_key :"#{underscore(demodulize(self[:model].name))}_id" end
Default foreign key name symbol for foreign key in join table that points to the association's table's primary key (or :right_primary_key column).
# File lib/sequel/model/associations.rb, line 1310 def default_right_key :"#{singularize(self[:name])}_id" end
many_to_many associations need to select a key in an associated table to eagerly load
# File lib/sequel/model/associations.rb, line 1343 def eager_loading_use_associated_key? !separate_query_per_table? end
# File lib/sequel/model/associations.rb, line 1326 def finalize_settings FINALIZE_SETTINGS end
The join table itself, unless it is aliased, in which case this is the alias.
# File lib/sequel/model/associations.rb, line 1355 def join_table_alias cached_fetch(:join_table_alias) do s, a = split_join_table_alias a || s end end
The source of the join table. This is the join table itself, unless it is aliased, in which case it is the unaliased part.
# File lib/sequel/model/associations.rb, line 1349 def join_table_source cached_fetch(:join_table_source){split_join_table_alias[0]} end
Whether the associated object needs a primary key to be added/removed, true for many_to_many associations.
# File lib/sequel/model/associations.rb, line 1365 def need_associated_primary_key? true end
The hash key to use for the eager loading predicate (left side of IN (1, 2, 3)). The left key qualified by the join table.
# File lib/sequel/model/associations.rb, line 1332 def predicate_key cached_fetch(:predicate_key){qualify(join_table_alias, self[:left_key])} end
The right key qualified by the join table.
# File lib/sequel/model/associations.rb, line 1338 def qualified_right_key cached_fetch(:qualified_right_key){qualify(join_table_alias, self[:right_key])} end
#right_primary_key qualified by the associated table
# File lib/sequel/model/associations.rb, line 1370 def qualified_right_primary_key cached_fetch(:qualified_right_primary_key){qualify_assoc(right_primary_key)} end
The primary key column(s) to use in the associated table (can be symbol or array).
# File lib/sequel/model/associations.rb, line 1375 def right_primary_key cached_fetch(:right_primary_key){associated_class.primary_key || raise(Error, "no primary key specified for #{associated_class.inspect}")} end
The method symbol or array of method symbols to call on the associated objects to get the foreign key values for the join table.
# File lib/sequel/model/associations.rb, line 1386 def right_primary_key_method cached_fetch(:right_primary_key_method){right_primary_key} end
The array of method symbols to call on the associated objects to get the foreign key values for the join table.
# File lib/sequel/model/associations.rb, line 1392 def right_primary_key_methods cached_fetch(:right_primary_key_methods){Array(right_primary_key_method)} end
The primary key columns to use in the associated table (always array).
# File lib/sequel/model/associations.rb, line 1380 def right_primary_keys cached_fetch(:right_primary_keys){Array(right_primary_key)} end
The columns to select when loading the association, associated_class.table_name.* by default.
# File lib/sequel/model/associations.rb, line 1397 def select cached_fetch(:select){default_select} end
Whether a separate query should be used for the join table.
# File lib/sequel/model/associations.rb, line 1402 def separate_query_per_table? self[:join_table_db] end
Private Instance Methods
Join to the the join table, unless using a separate query per table.
# File lib/sequel/model/associations.rb, line 1409 def _associated_dataset if separate_query_per_table? super else super.inner_join(self[:join_table], self[:right_keys].zip(right_primary_keys), :qualify=>:deep) end end
The default selection for associations that require joins. These do not use the default model selection unless all entries in the select are explicitly qualified identifiers, as other it can include unqualified columns which would be made ambiguous by joining.
# File lib/sequel/model/associations.rb, line 1430 def default_select if (sel = associated_class.dataset.opts[:select]) && sel.all?{|c| selection_is_qualified?(c)} sel else Sequel::SQL::ColumnAll.new(associated_class.table_name) end end
Use the right_keys from the eager loading options if using a separate query per table.
# File lib/sequel/model/associations.rb, line 1419 def eager_loading_set_predicate_condition(ds, eo) if separate_query_per_table? ds.where(right_primary_key=>eo[:right_keys]) else super end end
# File lib/sequel/model/associations.rb, line 1438 def filter_by_associations_conditions_associated_keys qualify(join_table_alias, self[:left_keys]) end
# File lib/sequel/model/associations.rb, line 1442 def filter_by_associations_conditions_key qualify(self[:model].table_name, self[:left_primary_key_column]) end
# File lib/sequel/model/associations.rb, line 1446 def filter_by_associations_limit_alias_key aliaz = 'a' filter_by_associations_limit_key.map{|c| c.as(Sequel.identifier(aliaz = aliaz.next))} end
# File lib/sequel/model/associations.rb, line 1451 def filter_by_associations_limit_aliases filter_by_associations_limit_alias_key.map(&:alias) end
# File lib/sequel/model/associations.rb, line 1455 def filter_by_associations_limit_key qualify(join_table_alias, self[:left_keys]) + Array(qualify(associated_class.table_name, associated_class.primary_key)) end
# File lib/sequel/model/associations.rb, line 1459 def predicate_key_methods self[:left_primary_keys] end
# File lib/sequel/model/associations.rb, line 1463 def reciprocal_association?(assoc_reflect) super && assoc_reflect[:left_keys] == self[:right_keys] && assoc_reflect[:right_keys] == self[:left_keys] && assoc_reflect[:join_table] == self[:join_table] && right_primary_keys == assoc_reflect[:left_primary_key_columns] && self[:left_primary_key_columns] == assoc_reflect.right_primary_keys end
# File lib/sequel/model/associations.rb, line 1471 def reciprocal_type :many_to_many end
Whether the given expression represents a qualified identifier. Used to determine if it is OK to use directly when joining.
# File lib/sequel/model/associations.rb, line 1477 def selection_is_qualified?(c) case c when Symbol Sequel.split_symbol(c)[0] when Sequel::SQL::QualifiedIdentifier true when Sequel::SQL::AliasedExpression selection_is_qualified?(c.expression) else false end end
Split the join table into source and alias parts.
# File lib/sequel/model/associations.rb, line 1491 def split_join_table_alias associated_class.dataset.split_alias(self[:join_table]) end