module ArelHelpers::JoinAssociation
Public Class Methods
join_association(table, association, join_type = Arel::Nodes::InnerJoin, options = {}, &block)
click to toggle source
activerecord uses JoinDependency to automagically generate inner join statements for any type of association (belongs_to, has_many, and has_and_belongs_to_many). For example, for HABTM associations, two join statements are required. This method encapsulates that functionality and yields an intermediate object for chaining. It also allows you to use an outer join instead of the default inner via the join_type arg.
# File lib/arel-helpers/join_association.rb, line 20 def join_association(table, association, join_type = Arel::Nodes::InnerJoin, options = {}, &block) if version >= "7.2.0" join_association_7_2_0(table, association, join_type, options, &block) elsif version >= '6.1.0' join_association_6_1_0(table, association, join_type, options, &block) elsif version >= '6.0.0' join_association_6_0_0(table, association, join_type, options, &block) elsif version >= '5.2.1' join_association_5_2_1(table, association, join_type, options, &block) elsif version >= '5.2.0' join_association_5_2(table, association, join_type, options, &block) elsif version >= '5.0.0' join_association_5_0(table, association, join_type, options, &block) elsif version >= '4.2.0' join_association_4_2(table, association, join_type, options, &block) elsif version >= '4.1.0' join_association_4_1(table, association, join_type, options, &block) else join_association_3_1(table, association, join_type, options, &block) end end
Private Class Methods
apply_aliases(node, aliases)
click to toggle source
# File lib/arel-helpers/join_association.rb, line 294 def apply_aliases(node, aliases) case node when Arel::Nodes::Join node.left = aliases[node.left.name] || node.left apply_aliases(node.right, aliases) when Arel::Attributes::Attribute node.relation = aliases[node.relation.name] || node.relation when Arel::Nodes::And node.children.each { |child| apply_aliases(child, aliases) } when Arel::Nodes::Unary apply_aliases(node.value, aliases) when Arel::Nodes::Binary apply_aliases(node.left, aliases) apply_aliases(node.right, aliases) end end
join_association_3_1(table, association, join_type, options = {}) { |left.to_sym, right| ... }
click to toggle source
# File lib/arel-helpers/join_association.rb, line 48 def join_association_3_1(table, association, join_type, options = {}) aliases = options.fetch(:aliases, []).index_by(&:table_name) associations = association.is_a?(Array) ? association : [association] join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, []) manager = Arel::SelectManager.new(table) join_dependency.join_associations.each do |assoc| assoc.join_type = join_type assoc.join_to(manager) end manager.join_sources.map do |assoc| assoc.left.table_alias = aliases[assoc.left.name].name if aliases.key?(assoc.left.name) if block_given? right = yield assoc.left.name.to_sym, assoc.right assoc.class.new(assoc.left, right) else assoc end end end
join_association_4_1(table, association, join_type, options = {}) { |left.to_sym, right| ... }
click to toggle source
# File lib/arel-helpers/join_association.rb, line 71 def join_association_4_1(table, association, join_type, options = {}) aliases = options.fetch(:aliases, []).index_by(&:table_name) associations = association.is_a?(Array) ? association : [association] join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, []) join_dependency.join_constraints([]).map do |constraint| right = if block_given? yield constraint.left.name.to_sym, constraint.right else constraint.right end constraint.left.table_alias = aliases[constraint.left.name].name if aliases.key?(constraint.left.name) join_type.new(constraint.left, right) end end
join_association_4_2(table, association, join_type, options = {}) { |left.to_sym, right| ... }
click to toggle source
ActiveRecord
4.2 moves bind variables out of the join classes and into the relation. For this reason, a method like join_association
isn’t able to add to the list of bind variables dynamically. To get around the problem, this method must return a string.
# File lib/arel-helpers/join_association.rb, line 94 def join_association_4_2(table, association, join_type, options = {}) aliases = options.fetch(:aliases, []).index_by(&:table_name) associations = association.is_a?(Array) ? association : [association] join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, []) constraints = join_dependency.join_constraints([]) binds = constraints.flat_map do |info| info.binds.map { |bv| table.connection.quote(*bv.reverse) } end joins = constraints.flat_map do |constraint| constraint.joins.map do |join| right = if block_given? yield join.left.name.to_sym, join.right else join.right end join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name) join_type.new(join.left, right) end end join_strings = joins.map do |join| to_sql(join, table, binds) end join_strings.join(' ') end
join_association_5_0(table, association, join_type, options = {}) { |left.to_sym, right| ... }
click to toggle source
# File lib/arel-helpers/join_association.rb, line 126 def join_association_5_0(table, association, join_type, options = {}) aliases = options.fetch(:aliases, []).index_by(&:table_name) associations = association.is_a?(Array) ? association : [association] join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, []) constraints = join_dependency.join_constraints([], join_type) binds = constraints.flat_map do |info| prepared_binds = info.binds.map(&:value_for_database) prepared_binds.map { |value| table.connection.quote(value) } end joins = constraints.flat_map do |constraint| constraint.joins.map do |join| right = if block_given? yield join.left.name.to_sym, join.right else join.right end join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name) join_type.new(join.left, right) end end join_strings = joins.map do |join| to_sql(join, table, binds) end join_strings.join(' ') end
join_association_5_2(table, association, join_type, options = {}) { |left.to_sym, right| ... }
click to toggle source
# File lib/arel-helpers/join_association.rb, line 159 def join_association_5_2(table, association, join_type, options = {}) aliases = options.fetch(:aliases, []).index_by(&:table_name) associations = association.is_a?(Array) ? association : [association] alias_tracker = ActiveRecord::Associations::AliasTracker.create( table.connection, table.name, {} ) join_dependency = ActiveRecord::Associations::JoinDependency.new( table, table.arel_table, associations, alias_tracker ) constraints = join_dependency.join_constraints([], join_type) constraints.map do |join| right = if block_given? yield join.left.name.to_sym, join.right else join.right end join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name) join_type.new(join.left, right) end end
join_association_5_2_1(table, association, join_type, options = {}) { |left.to_sym, right| ... }
click to toggle source
# File lib/arel-helpers/join_association.rb, line 186 def join_association_5_2_1(table, association, join_type, options = {}) aliases = options.fetch(:aliases, []).index_by(&:table_name) associations = association.is_a?(Array) ? association : [association] alias_tracker = ActiveRecord::Associations::AliasTracker.create( table.connection, table.name, {} ) join_dependency = ActiveRecord::Associations::JoinDependency.new( table, table.arel_table, associations ) constraints = join_dependency.join_constraints([], join_type, alias_tracker) constraints.map do |join| right = if block_given? yield join.left.name.to_sym, join.right else join.right end join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name) join_type.new(join.left, right) end end
join_association_6_0_0(table, association, join_type, options = {}) { |left.to_sym, right| ... }
click to toggle source
# File lib/arel-helpers/join_association.rb, line 213 def join_association_6_0_0(table, association, join_type, options = {}) aliases = options.fetch(:aliases, []).index_by(&:table_name) associations = association.is_a?(Array) ? association : [association] alias_tracker = ActiveRecord::Associations::AliasTracker.create( table.connection, table.name, {} ) join_dependency = ActiveRecord::Associations::JoinDependency.new( table, table.arel_table, associations, join_type ) constraints = join_dependency.join_constraints([], alias_tracker) constraints.map do |join| right = if block_given? yield join.left.name.to_sym, join.right else join.right end join.left.table_alias = aliases[join.left.name].name if aliases.key?(join.left.name) join_type.new(join.left, right) end end
join_association_6_1_0(table, association, join_type, options = {}) { |left.to_sym, right| ... }
click to toggle source
# File lib/arel-helpers/join_association.rb, line 240 def join_association_6_1_0(table, association, join_type, options = {}) aliases = options.fetch(:aliases, []).index_by(&:table_name) associations = association.is_a?(Array) ? association : [association] alias_tracker = ActiveRecord::Associations::AliasTracker.create( table.connection, table.name, {} ) join_dependency = ActiveRecord::Associations::JoinDependency.new( table, table.arel_table, associations, join_type ) constraints = join_dependency.join_constraints([], alias_tracker, []) constraints.map do |join| apply_aliases(join, aliases) right = if block_given? yield join.left.name.to_sym, join.right else join.right end join_type.new(join.left, right) end end
join_association_7_2_0(table, association, join_type, options = {}) { |left.to_sym, right| ... }
click to toggle source
# File lib/arel-helpers/join_association.rb, line 267 def join_association_7_2_0(table, association, join_type, options = {}) aliases = options.fetch(:aliases, []).index_by(&:table_name) associations = association.is_a?(Array) ? association : [association] alias_tracker = ActiveRecord::Associations::AliasTracker.create( table.connection_pool, table.name, {} ) join_dependency = ActiveRecord::Associations::JoinDependency.new( table, table.arel_table, associations, join_type ) constraints = join_dependency.join_constraints([], alias_tracker, []) constraints.map do |join| apply_aliases(join, aliases) right = if block_given? yield join.left.name.to_sym, join.right else join.right end join_type.new(join.left, right) end end
to_sql(node, table, binds)
click to toggle source
# File lib/arel-helpers/join_association.rb, line 313 def to_sql(node, table, binds) visitor = table.connection.visitor collect = visitor.accept(node, Arel::Collectors::Bind.new) collect.substitute_binds(binds).join end
version()
click to toggle source
# File lib/arel-helpers/join_association.rb, line 44 def version ActiveRecord::VERSION::STRING end