From d7db6a88734c3b666f4b85f266d223eff408b294 Mon Sep 17 00:00:00 2001 From: Josh Kalderimis Date: Fri, 19 Nov 2010 18:29:33 +0100 Subject: class inheritable attributes is used no more! all internal use of class inheritable has been changed to class_attribute. class inheritable attributes has been deprecated. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- activerecord/lib/active_record/associations/association_collection.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 6090376bb8..774103342a 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -530,7 +530,7 @@ module ActiveRecord def callbacks_for(callback_name) full_callback_name = "#{callback_name}_for_#{@reflection.name}" - @owner.class.read_inheritable_attribute(full_callback_name.to_sym) || [] + @owner.class.send(full_callback_name.to_sym) || [] end def ensure_owner_is_not_new -- cgit v1.2.3 From 4d31ee1e0e2eccae0c9964214455ff75c647bd7f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 22 Nov 2010 16:14:37 -0800 Subject: removing unused variables --- .../lib/active_record/associations/through_association_scope.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb index bd8e304e99..acddfda924 100644 --- a/activerecord/lib/active_record/associations/through_association_scope.rb +++ b/activerecord/lib/active_record/associations/through_association_scope.rb @@ -16,7 +16,7 @@ module ActiveRecord :readonly => @reflection.options[:readonly] } end - + def construct_create_scope construct_owner_attributes(@reflection) end @@ -51,7 +51,7 @@ module ActiveRecord def construct_select(custom_select = nil) distinct = "DISTINCT " if @reflection.options[:uniq] - selected = custom_select || @reflection.options[:select] || "#{distinct}#{@reflection.quoted_table_name}.*" + custom_select || @reflection.options[:select] || "#{distinct}#{@reflection.quoted_table_name}.*" end def construct_joins(custom_joins = nil) -- cgit v1.2.3 From 4ece7e06fd0009f024fd167107324122c564d551 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 22 Nov 2010 17:06:55 -0800 Subject: removing space error --- activerecord/lib/active_record/associations/belongs_to_association.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index b624951cd9..b438620c8f 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -61,7 +61,7 @@ module ActiveRecord set_inverse_instance(the_target, @owner) the_target end - + def construct_find_scope { :conditions => conditions } end -- cgit v1.2.3 From 1b531b7ee2054beadb23853d79b15d588b9ffd88 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Sun, 21 Nov 2010 00:35:11 +0800 Subject: Remove explicit return. --- activerecord/lib/active_record/associations/has_many_association.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 830a82980d..a682ec52d8 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -46,7 +46,7 @@ module ActiveRecord count = [ @reflection.options[:limit], count ].min end - return count + count end def has_cached_counter? -- cgit v1.2.3 From 63c9185b62076f416c63b472a356bf9faac143db Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Sun, 21 Nov 2010 00:38:35 +0800 Subject: Remove explicit return and avoid creating local var. --- activerecord/lib/active_record/associations/has_many_association.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index a682ec52d8..6423536fb9 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -112,8 +112,7 @@ module ActiveRecord end def we_can_set_the_inverse_on_this?(record) - inverse = @reflection.inverse_of - return !inverse.nil? + !@reflection.inverse_of.nil? end end end -- cgit v1.2.3 From 9f35799221c8a3c06b3f34a38525654b59598cfd Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Sat, 20 Nov 2010 13:37:54 -0300 Subject: Refactor && simplify count_records. --- activerecord/lib/active_record/associations/has_many_association.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 6423536fb9..23831e0b08 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -42,11 +42,7 @@ module ActiveRecord # documented side-effect of the method that may avoid an extra SELECT. @target ||= [] and loaded if count == 0 - if @reflection.options[:limit] - count = [ @reflection.options[:limit], count ].min - end - - count + @reflection.options[:limit] ? [@reflection.options[:limit], count].min : count end def has_cached_counter? -- cgit v1.2.3 From 1aaa8edeb958a263c7a256344f442867c4b90c5f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 23 Nov 2010 17:34:18 -0800 Subject: breaking classes up in to respective files --- .../associations/class_methods/join_dependency.rb | 216 ++++++++++++++++ .../join_dependency/join_association.rb | 278 +++++++++++++++++++++ .../class_methods/join_dependency/join_base.rb | 34 +++ .../class_methods/join_dependency/join_part.rb | 76 ++++++ 4 files changed, 604 insertions(+) create mode 100644 activerecord/lib/active_record/associations/class_methods/join_dependency.rb create mode 100644 activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb create mode 100644 activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb create mode 100644 activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb new file mode 100644 index 0000000000..79fdb2d4cb --- /dev/null +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -0,0 +1,216 @@ +require 'active_record/associations/class_methods/join_dependency/join_part' +require 'active_record/associations/class_methods/join_dependency/join_base' +require 'active_record/associations/class_methods/join_dependency/join_association' + +module ActiveRecord + module Associations + module ClassMethods + class JoinDependency # :nodoc: + attr_reader :join_parts, :reflections, :table_aliases + + def initialize(base, associations, joins) + @join_parts = [JoinBase.new(base, joins)] + @associations = {} + @reflections = [] + @table_aliases = Hash.new(0) + @table_aliases[base.table_name] = 1 + build(associations) + end + + def graft(*associations) + associations.each do |association| + join_associations.detect {|a| association == a} || + build(association.reflection.name, association.find_parent_in(self) || join_base, association.join_type) + end + self + end + + def join_associations + join_parts.last(join_parts.length - 1) + end + + def join_base + join_parts.first + end + + def count_aliases_from_table_joins(name) + # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase + quoted_name = join_base.active_record.connection.quote_table_name(name.downcase).downcase + join_sql = join_base.table_joins.to_s.downcase + join_sql.blank? ? 0 : + # Table names + join_sql.scan(/join(?:\s+\w+)?\s+#{quoted_name}\son/).size + + # Table aliases + join_sql.scan(/join(?:\s+\w+)?\s+\S+\s+#{quoted_name}\son/).size + end + + def instantiate(rows) + primary_key = join_base.aliased_primary_key + parents = {} + + records = rows.map { |model| + primary_id = model[primary_key] + parent = parents[primary_id] ||= join_base.instantiate(model) + construct(parent, @associations, join_associations.dup, model) + parent + }.uniq + + remove_duplicate_results!(join_base.active_record, records, @associations) + records + end + + def remove_duplicate_results!(base, records, associations) + case associations + when Symbol, String + reflection = base.reflections[associations] + remove_uniq_by_reflection(reflection, records) + when Array + associations.each do |association| + remove_duplicate_results!(base, records, association) + end + when Hash + associations.keys.each do |name| + reflection = base.reflections[name] + remove_uniq_by_reflection(reflection, records) + + parent_records = [] + records.each do |record| + if descendant = record.send(reflection.name) + if reflection.collection? + parent_records.concat descendant.target.uniq + else + parent_records << descendant + end + end + end + + remove_duplicate_results!(reflection.klass, parent_records, associations[name]) unless parent_records.empty? + end + end + end + + protected + + def cache_joined_association(association) + associations = [] + parent = association.parent + while parent != join_base + associations.unshift(parent.reflection.name) + parent = parent.parent + end + ref = @associations + associations.each do |key| + ref = ref[key] + end + ref[association.reflection.name] ||= {} + end + + def build(associations, parent = nil, join_type = Arel::InnerJoin) + parent ||= join_parts.last + case associations + when Symbol, String + reflection = parent.reflections[associations.to_s.intern] or + raise ConfigurationError, "Association named '#{ associations }' was not found; perhaps you misspelled it?" + unless join_association = find_join_association(reflection, parent) + @reflections << reflection + join_association = build_join_association(reflection, parent) + join_association.join_type = join_type + @join_parts << join_association + cache_joined_association(join_association) + end + join_association + when Array + associations.each do |association| + build(association, parent, join_type) + end + when Hash + associations.keys.sort{|a,b|a.to_s<=>b.to_s}.each do |name| + join_association = build(name, parent, join_type) + build(associations[name], join_association, join_type) + end + else + raise ConfigurationError, associations.inspect + end + end + + def find_join_association(name_or_reflection, parent) + if String === name_or_reflection + name_or_reflection = name_or_reflection.to_sym + end + + join_associations.detect { |j| + j.reflection == name_or_reflection && j.parent == parent + } + end + + def remove_uniq_by_reflection(reflection, records) + if reflection && reflection.collection? + records.each { |record| record.send(reflection.name).target.uniq! } + end + end + + def build_join_association(reflection, parent) + JoinAssociation.new(reflection, self, parent) + end + + def construct(parent, associations, join_parts, row) + case associations + when Symbol, String + name = associations.to_s + + join_part = join_parts.detect { |j| + j.reflection.name.to_s == name && + j.parent_table_name == parent.class.table_name } + + raise(ConfigurationError, "No such association") unless join_part + + join_parts.delete(join_part) + construct_association(parent, join_part, row) + when Array + associations.each do |association| + construct(parent, association, join_parts, row) + end + when Hash + associations.sort_by { |k,_| k.to_s }.each do |name, assoc| + association = construct(parent, name, join_parts, row) + construct(association, assoc, join_parts, row) if association + end + else + raise ConfigurationError, associations.inspect + end + end + + def construct_association(record, join_part, row) + return if record.id.to_s != join_part.parent.record_id(row).to_s + + macro = join_part.reflection.macro + if macro == :has_one + return if record.instance_variable_defined?("@#{join_part.reflection.name}") + association = join_part.instantiate(row) unless row[join_part.aliased_primary_key].nil? + set_target_and_inverse(join_part, association, record) + else + return if row[join_part.aliased_primary_key].nil? + association = join_part.instantiate(row) + case macro + when :has_many, :has_and_belongs_to_many + collection = record.send(join_part.reflection.name) + collection.loaded + collection.target.push(association) + collection.__send__(:set_inverse_instance, association, record) + when :belongs_to + set_target_and_inverse(join_part, association, record) + else + raise ConfigurationError, "unknown macro: #{join_part.reflection.macro}" + end + end + association + end + + def set_target_and_inverse(join_part, association, record) + association_proxy = record.send("set_#{join_part.reflection.name}_target", association) + association_proxy.__send__(:set_inverse_instance, association, record) + end + end + end + end +end diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb new file mode 100644 index 0000000000..5e5c01c77a --- /dev/null +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -0,0 +1,278 @@ +module ActiveRecord + module Associations + module ClassMethods + class JoinDependency # :nodoc: + class JoinAssociation < JoinPart # :nodoc: + # The reflection of the association represented + attr_reader :reflection + + # The JoinDependency object which this JoinAssociation exists within. This is mainly + # relevant for generating aliases which do not conflict with other joins which are + # part of the query. + attr_reader :join_dependency + + # A JoinBase instance representing the active record we are joining onto. + # (So in Author.has_many :posts, the Author would be that base record.) + attr_reader :parent + + # What type of join will be generated, either Arel::InnerJoin (default) or Arel::OuterJoin + attr_accessor :join_type + + # These implement abstract methods from the superclass + attr_reader :aliased_prefix, :aliased_table_name + + delegate :options, :through_reflection, :source_reflection, :to => :reflection + delegate :table, :table_name, :to => :parent, :prefix => true + + def initialize(reflection, join_dependency, parent = nil) + reflection.check_validity! + + if reflection.options[:polymorphic] + raise EagerLoadPolymorphicError.new(reflection) + end + + super(reflection.klass) + + @reflection = reflection + @join_dependency = join_dependency + @parent = parent + @join_type = Arel::InnerJoin + + # This must be done eagerly upon initialisation because the alias which is produced + # depends on the state of the join dependency, but we want it to work the same way + # every time. + allocate_aliases + end + + def ==(other) + other.class == self.class && + other.reflection == reflection && + other.parent == parent + end + + def find_parent_in(other_join_dependency) + other_join_dependency.join_parts.detect do |join_part| + self.parent == join_part + end + end + + def join_to(relation) + send("join_#{reflection.macro}_to", relation) + end + + def join_relation(joining_relation) + self.join_type = Arel::OuterJoin + joining_relation.joins(self) + end + + def table + @table ||= Arel::Table.new( + table_name, :as => aliased_table_name, + :engine => arel_engine, :columns => active_record.columns + ) + end + + # More semantic name given we are talking about associations + alias_method :target_table, :table + + protected + + def aliased_table_name_for(name, suffix = nil) + if @join_dependency.table_aliases[name].zero? + @join_dependency.table_aliases[name] = @join_dependency.count_aliases_from_table_joins(name) + end + + if !@join_dependency.table_aliases[name].zero? # We need an alias + name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}" + @join_dependency.table_aliases[name] += 1 + if @join_dependency.table_aliases[name] == 1 # First time we've seen this name + # Also need to count the aliases from the table_aliases to avoid incorrect count + @join_dependency.table_aliases[name] += @join_dependency.count_aliases_from_table_joins(name) + end + table_index = @join_dependency.table_aliases[name] + name = name[0..active_record.connection.table_alias_length-3] + "_#{table_index}" if table_index > 1 + else + @join_dependency.table_aliases[name] += 1 + end + + name + end + + def pluralize(table_name) + ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name + end + + def interpolate_sql(sql) + instance_eval("%@#{sql.gsub('@', '\@')}@", __FILE__, __LINE__) + end + + private + + def allocate_aliases + @aliased_prefix = "t#{ join_dependency.join_parts.size }" + @aliased_table_name = aliased_table_name_for(table_name) + + if reflection.macro == :has_and_belongs_to_many + @aliased_join_table_name = aliased_table_name_for(reflection.options[:join_table], "_join") + elsif [:has_many, :has_one].include?(reflection.macro) && reflection.options[:through] + @aliased_join_table_name = aliased_table_name_for(reflection.through_reflection.klass.table_name, "_join") + end + end + + def process_conditions(conditions, table_name) + Arel.sql(interpolate_sql(sanitize_sql(conditions, table_name))) + end + + def join_target_table(relation, *conditions) + relation = relation.join(target_table, join_type) + + # If the target table is an STI model then we must be sure to only include records of + # its type and its sub-types. + unless active_record.descends_from_active_record? + sti_column = target_table[active_record.inheritance_column] + + sti_condition = sti_column.eq(active_record.sti_name) + active_record.descendants.each do |subclass| + sti_condition = sti_condition.or(sti_column.eq(subclass.sti_name)) + end + + conditions << sti_condition + end + + # If the reflection has conditions, add them + if options[:conditions] + conditions << process_conditions(options[:conditions], aliased_table_name) + end + + relation = relation.on(*conditions) + end + + def join_has_and_belongs_to_many_to(relation) + join_table = Arel::Table.new( + options[:join_table], :engine => arel_engine, + :as => @aliased_join_table_name + ) + + fk = options[:foreign_key] || reflection.active_record.to_s.foreign_key + klass_fk = options[:association_foreign_key] || reflection.klass.to_s.foreign_key + + relation = relation.join(join_table, join_type) + relation = relation.on( + join_table[fk]. + eq(parent_table[reflection.active_record.primary_key]) + ) + + join_target_table( + relation, + target_table[reflection.klass.primary_key]. + eq(join_table[klass_fk]) + ) + end + + def join_has_many_to(relation) + if reflection.options[:through] + join_has_many_through_to(relation) + elsif reflection.options[:as] + join_has_many_polymorphic_to(relation) + else + foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key + primary_key = options[:primary_key] || parent.primary_key + + join_target_table( + relation, + target_table[foreign_key]. + eq(parent_table[primary_key]) + ) + end + end + alias :join_has_one_to :join_has_many_to + + def join_has_many_through_to(relation) + join_table = Arel::Table.new( + through_reflection.klass.table_name, :engine => arel_engine, + :as => @aliased_join_table_name + ) + + jt_conditions = [] + jt_foreign_key = first_key = second_key = nil + + if through_reflection.options[:as] # has_many :through against a polymorphic join + as_key = through_reflection.options[:as].to_s + jt_foreign_key = as_key + '_id' + + jt_conditions << + join_table[as_key + '_type']. + eq(parent.active_record.base_class.name) + else + jt_foreign_key = through_reflection.primary_key_name + end + + case source_reflection.macro + when :has_many + second_key = options[:foreign_key] || primary_key + + if source_reflection.options[:as] + first_key = "#{source_reflection.options[:as]}_id" + else + first_key = through_reflection.klass.base_class.to_s.foreign_key + end + + unless through_reflection.klass.descends_from_active_record? + jt_conditions << + join_table[through_reflection.active_record.inheritance_column]. + eq(through_reflection.klass.sti_name) + end + when :belongs_to + first_key = primary_key + + if reflection.options[:source_type] + second_key = source_reflection.association_foreign_key + + jt_conditions << + join_table[reflection.source_reflection.options[:foreign_type]]. + eq(reflection.options[:source_type]) + else + second_key = source_reflection.primary_key_name + end + end + + jt_conditions << + parent_table[parent.primary_key]. + eq(join_table[jt_foreign_key]) + + if through_reflection.options[:conditions] + jt_conditions << process_conditions(through_reflection.options[:conditions], aliased_table_name) + end + + relation = relation.join(join_table, join_type).on(*jt_conditions) + + join_target_table( + relation, + target_table[first_key].eq(join_table[second_key]) + ) + end + + def join_has_many_polymorphic_to(relation) + join_target_table( + relation, + target_table["#{reflection.options[:as]}_id"]. + eq(parent_table[parent.primary_key]), + target_table["#{reflection.options[:as]}_type"]. + eq(parent.active_record.base_class.name) + ) + end + + def join_belongs_to_to(relation) + foreign_key = options[:foreign_key] || reflection.primary_key_name + primary_key = options[:primary_key] || reflection.klass.primary_key + + join_target_table( + relation, + target_table[primary_key].eq(parent_table[foreign_key]) + ) + end + end + end + end + end +end diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb new file mode 100644 index 0000000000..ed05003f66 --- /dev/null +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb @@ -0,0 +1,34 @@ +module ActiveRecord + module Associations + module ClassMethods + class JoinDependency # :nodoc: + class JoinBase < JoinPart # :nodoc: + # Extra joins provided when the JoinDependency was created + attr_reader :table_joins + + def initialize(active_record, joins = nil) + super(active_record) + @table_joins = joins + end + + def ==(other) + other.class == self.class && + other.active_record == active_record + end + + def aliased_prefix + "t0" + end + + def table + Arel::Table.new(table_name, :engine => arel_engine, :columns => active_record.columns) + end + + def aliased_table_name + active_record.table_name + end + end + end + end + end +end diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb new file mode 100644 index 0000000000..64d751344d --- /dev/null +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb @@ -0,0 +1,76 @@ +module ActiveRecord + module Associations + module ClassMethods + class JoinDependency # :nodoc: + # A JoinPart represents a part of a JoinDependency. It is an abstract class, inherited + # by JoinBase and JoinAssociation. A JoinBase represents the Active Record which + # everything else is being joined onto. A JoinAssociation represents an association which + # is joining to the base. A JoinAssociation may result in more than one actual join + # operations (for example a has_and_belongs_to_many JoinAssociation would result in + # two; one for the join table and one for the target table). + class JoinPart # :nodoc: + # The Active Record class which this join part is associated 'about'; for a JoinBase + # this is the actual base model, for a JoinAssociation this is the target model of the + # association. + attr_reader :active_record + + delegate :table_name, :column_names, :primary_key, :reflections, :sanitize_sql, :arel_engine, :to => :active_record + + def initialize(active_record) + @active_record = active_record + @cached_record = {} + end + + def ==(other) + raise NotImplementedError + end + + # An Arel::Table for the active_record + def table + raise NotImplementedError + end + + # The prefix to be used when aliasing columns in the active_record's table + def aliased_prefix + raise NotImplementedError + end + + # The alias for the active_record's table + def aliased_table_name + raise NotImplementedError + end + + # The alias for the primary key of the active_record's table + def aliased_primary_key + "#{aliased_prefix}_r0" + end + + # An array of [column_name, alias] pairs for the table + def column_names_with_alias + unless defined?(@column_names_with_alias) + @column_names_with_alias = [] + + ([primary_key] + (column_names - [primary_key])).each_with_index do |column_name, i| + @column_names_with_alias << [column_name, "#{aliased_prefix}_r#{i}"] + end + end + + @column_names_with_alias + end + + def extract_record(row) + Hash[column_names_with_alias.map{|cn, an| [cn, row[an]]}] + end + + def record_id(row) + row[aliased_primary_key] + end + + def instantiate(row) + @cached_record[record_id(row)] ||= active_record.send(:instantiate, extract_record(row)) + end + end + end + end + end +end -- cgit v1.2.3 From 0687b21de879d53157e52a2b688e34a1bd1e31f0 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 23 Nov 2010 17:52:51 -0800 Subject: removing ternary --- activerecord/lib/active_record/associations/has_many_association.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 23831e0b08..156279a67a 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -42,7 +42,7 @@ module ActiveRecord # documented side-effect of the method that may avoid an extra SELECT. @target ||= [] and loaded if count == 0 - @reflection.options[:limit] ? [@reflection.options[:limit], count].min : count + [@reflection.options[:limit], count].compact.min end def has_cached_counter? -- cgit v1.2.3 From a3ba60fd814a980cc929fcbe0f9d48fa4d0292e5 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 23 Nov 2010 18:08:23 -0800 Subject: reduce method calls --- activerecord/lib/active_record/associations/has_many_association.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 156279a67a..685d818ab3 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -108,7 +108,7 @@ module ActiveRecord end def we_can_set_the_inverse_on_this?(record) - !@reflection.inverse_of.nil? + @reflection.inverse_of end end end -- cgit v1.2.3 From d4b8d3bafa54e233d3f1ef43c43bfb460d9f2435 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 24 Nov 2010 13:29:18 -0800 Subject: moving column_aliases to JoinDependency --- .../active_record/associations/class_methods/join_dependency.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 79fdb2d4cb..87541e0529 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -33,6 +33,14 @@ module ActiveRecord join_parts.first end + def columns(connection) + join_parts.collect { |join_part| + join_part.column_names_with_alias.collect{ |column_name, aliased_name| + "#{connection.quote_table_name join_part.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}" + } + }.flatten.join(", ") + end + def count_aliases_from_table_joins(name) # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase quoted_name = join_base.active_record.connection.quote_table_name(name.downcase).downcase -- cgit v1.2.3 From afe51afcc6b7c0245fddbd879d369818b54e460a Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 24 Nov 2010 13:32:01 -0800 Subject: remove useless join --- .../lib/active_record/associations/class_methods/join_dependency.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 87541e0529..7c7fa964f8 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -38,7 +38,7 @@ module ActiveRecord join_part.column_names_with_alias.collect{ |column_name, aliased_name| "#{connection.quote_table_name join_part.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}" } - }.flatten.join(", ") + }.flatten end def count_aliases_from_table_joins(name) -- cgit v1.2.3 From cdf6cf01cb47bdcbc1e011c8f5f72b161f12bf9c Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 24 Nov 2010 13:40:23 -0800 Subject: use ARel rather than generate SQL strings --- .../lib/active_record/associations/class_methods/join_dependency.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 7c7fa964f8..b1521b3706 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -33,10 +33,11 @@ module ActiveRecord join_parts.first end - def columns(connection) + def columns join_parts.collect { |join_part| + table = Arel::Nodes::TableAlias.new join_part.aliased_table_name, nil join_part.column_names_with_alias.collect{ |column_name, aliased_name| - "#{connection.quote_table_name join_part.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}" + table[column_name].as aliased_name } }.flatten end -- cgit v1.2.3 From 34d21b87bb237bf55214bd476be71116a2a5258f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 24 Nov 2010 13:53:55 -0800 Subject: adding a factory method to the join part for generating a table alias --- .../lib/active_record/associations/class_methods/join_dependency.rb | 2 +- .../associations/class_methods/join_dependency/join_part.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index b1521b3706..19d2d55ca0 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -35,7 +35,7 @@ module ActiveRecord def columns join_parts.collect { |join_part| - table = Arel::Nodes::TableAlias.new join_part.aliased_table_name, nil + table = join_part.aliased_table join_part.column_names_with_alias.collect{ |column_name, aliased_name| table[column_name].as aliased_name } diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb index 64d751344d..5d55ca202e 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb @@ -21,6 +21,10 @@ module ActiveRecord @cached_record = {} end + def aliased_table + Arel::Nodes::TableAlias.new aliased_table_name, table + end + def ==(other) raise NotImplementedError end -- cgit v1.2.3 From 38eb01863c9281d142c6494bae485b9c215ec9b7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 24 Nov 2010 14:11:12 -0800 Subject: initialize instance variables in initialize... o_O --- .../associations/class_methods/join_dependency/join_part.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb index 5d55ca202e..0b093b65e9 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb @@ -19,6 +19,7 @@ module ActiveRecord def initialize(active_record) @active_record = active_record @cached_record = {} + @column_names_with_alias = nil end def aliased_table @@ -51,14 +52,13 @@ module ActiveRecord # An array of [column_name, alias] pairs for the table def column_names_with_alias - unless defined?(@column_names_with_alias) + unless @column_names_with_alias @column_names_with_alias = [] ([primary_key] + (column_names - [primary_key])).each_with_index do |column_name, i| @column_names_with_alias << [column_name, "#{aliased_prefix}_r#{i}"] end end - @column_names_with_alias end -- cgit v1.2.3 From ee74f2c6238dbaca00e9b667c3c239f3cae8aca5 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 24 Nov 2010 14:16:38 -0800 Subject: alias should be a SQL literal --- .../lib/active_record/associations/class_methods/join_dependency.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 19d2d55ca0..6ab7bd0b06 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -37,7 +37,7 @@ module ActiveRecord join_parts.collect { |join_part| table = join_part.aliased_table join_part.column_names_with_alias.collect{ |column_name, aliased_name| - table[column_name].as aliased_name + table[column_name].as Arel.sql(aliased_name) } }.flatten end -- cgit v1.2.3 From ac6e9447e521a6ab2e3b60acd00a1ae2b863329e Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Thu, 25 Nov 2010 16:11:53 -0300 Subject: Remove return, we are already returning self. Signed-off-by: Santiago Pastorino --- .../lib/active_record/associations/association_collection.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 774103342a..8a98c0fcbe 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -235,12 +235,12 @@ module ActiveRecord # Removes all records from this association. Returns +self+ so method calls may be chained. def clear - return self if length.zero? # forces load_target if it hasn't happened already - - if @reflection.options[:dependent] && @reflection.options[:dependent] == :destroy - destroy_all - else - delete_all + unless length.zero? # forces load_target if it hasn't happened already + if @reflection.options[:dependent] && @reflection.options[:dependent] == :destroy + destroy_all + else + delete_all + end end self -- cgit v1.2.3 From c91a13f8f557cc1d21fccb5f964d50438cd60a52 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Thu, 25 Nov 2010 16:12:30 -0300 Subject: Use ternary instead explicit return. Signed-off-by: Santiago Pastorino --- activerecord/lib/active_record/associations/association_collection.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 8a98c0fcbe..e4e5ffd2b3 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -357,8 +357,7 @@ module ActiveRecord return false unless record.is_a?(@reflection.klass) return include_in_memory?(record) unless record.persisted? load_target if @reflection.options[:finder_sql] && !loaded? - return @target.include?(record) if loaded? - exists?(record) + loaded? ? @target.include?(record) : exists?(record) end def proxy_respond_to?(method, include_private = false) -- cgit v1.2.3 From a3bd62e1bae64569d0c2d45f8068f291e3e0e776 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Thu, 25 Nov 2010 16:12:57 -0300 Subject: Remove explicit return. Signed-off-by: Santiago Pastorino --- .../active_record/associations/has_and_belongs_to_many_association.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index da742fa668..2c72fd0004 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -67,7 +67,7 @@ module ActiveRecord relation.insert(attributes) end - return true + true end def delete_records(records) @@ -80,7 +80,7 @@ module ActiveRecord ).delete end end - + def construct_joins "INNER JOIN #{@owner.connection.quote_table_name @reflection.options[:join_table]} ON #{@reflection.quoted_table_name}.#{@reflection.klass.primary_key} = #{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.association_foreign_key}" end -- cgit v1.2.3 From 438c0188f8aa07d0e9895a2c13886901ca40ed5e Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 25 Nov 2010 20:00:40 -0200 Subject: nil check unneeded ht. exviva --- activerecord/lib/active_record/associations/association_collection.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index e4e5ffd2b3..ba9373ba6a 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -236,7 +236,7 @@ module ActiveRecord # Removes all records from this association. Returns +self+ so method calls may be chained. def clear unless length.zero? # forces load_target if it hasn't happened already - if @reflection.options[:dependent] && @reflection.options[:dependent] == :destroy + if @reflection.options[:dependent] == :destroy destroy_all else delete_all -- cgit v1.2.3 From e444439fe28f873c783a4b99b1c9f29a7405dd0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 28 Nov 2010 16:55:48 +0100 Subject: Partialy revert f1c13b0dd7b22b5f6289ca1a09f1d7a8c7c8584b --- .../associations/association_collection.rb | 22 +++++++++++----------- .../associations/association_proxy.rb | 2 +- .../has_and_belongs_to_many_association.rb | 4 ++-- .../associations/has_many_through_association.rb | 4 ++-- .../associations/has_one_association.rb | 2 +- .../associations/has_one_through_association.rb | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index ba9373ba6a..abb17a11c6 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -121,13 +121,13 @@ module ActiveRecord # Since << flattens its argument list and inserts each record, +push+ and +concat+ behave identically. def <<(*records) result = true - load_target unless @owner.persisted? + load_target if @owner.new_record? transaction do flatten_deeper(records).each do |record| raise_on_type_mismatch(record) add_record_to_target_with_callbacks(record) do |r| - result &&= insert_record(record) if @owner.persisted? + result &&= insert_record(record) unless @owner.new_record? end end end @@ -286,12 +286,12 @@ module ActiveRecord # This method is abstract in the sense that it relies on # +count_records+, which is a method descendants have to provide. def size - if !@owner.persisted? || (loaded? && !@reflection.options[:uniq]) + if @owner.new_record? || (loaded? && !@reflection.options[:uniq]) @target.size elsif !loaded? && @reflection.options[:group] load_target.size elsif !loaded? && !@reflection.options[:uniq] && @target.is_a?(Array) - unsaved_records = @target.reject { |r| r.persisted? } + unsaved_records = @target.select { |r| r.new_record? } unsaved_records.size + count_records else count_records @@ -355,7 +355,7 @@ module ActiveRecord def include?(record) return false unless record.is_a?(@reflection.klass) - return include_in_memory?(record) unless record.persisted? + return include_in_memory?(record) if record.new_record? load_target if @reflection.options[:finder_sql] && !loaded? loaded? ? @target.include?(record) : exists?(record) end @@ -369,7 +369,7 @@ module ActiveRecord end def load_target - if @owner.persisted? || foreign_key_present + if !@owner.new_record? || foreign_key_present begin unless loaded? if @target.is_a?(Array) && @target.any? @@ -478,7 +478,7 @@ module ActiveRecord private def create_record(attrs) attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash) - ensure_owner_is_not_new + ensure_owner_is_persisted! scoped_where = scoped.where_values_hash create_scope = scoped_where ? @scope[:create].merge(scoped_where) : @scope[:create] @@ -508,7 +508,7 @@ module ActiveRecord transaction do records.each { |record| callback(:before_remove, record) } - old_records = records.select { |r| r.persisted? } + old_records = records.reject { |r| r.new_record? } yield(records, old_records) records.each { |record| callback(:after_remove, record) } end @@ -532,15 +532,15 @@ module ActiveRecord @owner.class.send(full_callback_name.to_sym) || [] end - def ensure_owner_is_not_new + def ensure_owner_is_persisted! unless @owner.persisted? raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved" end end def fetch_first_or_last_using_find?(args) - (args.first.kind_of?(Hash) && !args.first.empty?) || !(loaded? || !@owner.persisted? || @reflection.options[:finder_sql] || - !@target.all? { |record| record.persisted? } || args.first.kind_of?(Integer)) + (args.first.kind_of?(Hash) && !args.first.empty?) || !(loaded? || @owner.new_record? || @reflection.options[:finder_sql] || + @target.any? { |record| record.new_record? } || args.first.kind_of?(Integer)) end def include_in_memory?(record) diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb index 7cd04a1ad5..252ff7e7ea 100644 --- a/activerecord/lib/active_record/associations/association_proxy.rb +++ b/activerecord/lib/active_record/associations/association_proxy.rb @@ -252,7 +252,7 @@ module ActiveRecord def load_target return nil unless defined?(@loaded) - if !loaded? and (@owner.persisted? || foreign_key_present) + if !loaded? && (!@owner.new_record? || foreign_key_present) @target = find_target end diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index 2c72fd0004..f6f291a039 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -34,7 +34,7 @@ module ActiveRecord end def insert_record(record, force = true, validate = true) - unless record.persisted? + if record.new_record? if force record.save! else @@ -113,7 +113,7 @@ module ActiveRecord private def create_record(attributes, &block) # Can't use Base.create because the foreign key may be a protected attribute. - ensure_owner_is_not_new + ensure_owner_is_persisted! if attributes.is_a?(Array) attributes.collect { |attr| create(attr) } else diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 79c229d9c4..d0c8af1801 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -36,7 +36,7 @@ module ActiveRecord protected def create_record(attrs, force = true) - ensure_owner_is_not_new + ensure_owner_is_persisted! transaction do object = @reflection.klass.new(attrs) @@ -59,7 +59,7 @@ module ActiveRecord end def insert_record(record, force = true, validate = true) - unless record.persisted? + if record.new_record? if force record.save! else diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index e6e037441f..c49fd6e66a 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -56,7 +56,7 @@ module ActiveRecord set_inverse_instance(obj, @owner) @loaded = true - unless !@owner.persisted? or obj.nil? or dont_save + unless !@owner.persisted? || obj.nil? || dont_save return (obj.save ? self : false) else return (obj.nil? ? nil : self) diff --git a/activerecord/lib/active_record/associations/has_one_through_association.rb b/activerecord/lib/active_record/associations/has_one_through_association.rb index 6e98f7dffb..7f28abf464 100644 --- a/activerecord/lib/active_record/associations/has_one_through_association.rb +++ b/activerecord/lib/active_record/associations/has_one_through_association.rb @@ -21,7 +21,7 @@ module ActiveRecord if current_object new_value ? current_object.update_attributes(construct_join_attributes(new_value)) : current_object.destroy elsif new_value - unless @owner.persisted? + if @owner.new_record? self.target = new_value through_association = @owner.send(:association_instance_get, @reflection.through_reflection.name) through_association.build(construct_join_attributes(new_value)) -- cgit v1.2.3 From 439a7dc0e62858a5ed1fc397e36626f9be1d7c87 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 29 Nov 2010 10:39:33 -0800 Subject: moving method to subclass that actually uses the method --- .../associations/class_methods/join_dependency/join_association.rb | 4 ++++ .../associations/class_methods/join_dependency/join_part.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 5e5c01c77a..e7d1ffa9f2 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -123,6 +123,10 @@ module ActiveRecord Arel.sql(interpolate_sql(sanitize_sql(conditions, table_name))) end + def sanitize_sql(condition, table_name) + active_record.send(:sanitize_sql, condition, table_name) + end + def join_target_table(relation, *conditions) relation = relation.join(target_table, join_type) diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb index 0b093b65e9..cd16ae5a8b 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_part.rb @@ -14,7 +14,7 @@ module ActiveRecord # association. attr_reader :active_record - delegate :table_name, :column_names, :primary_key, :reflections, :sanitize_sql, :arel_engine, :to => :active_record + delegate :table_name, :column_names, :primary_key, :reflections, :arel_engine, :to => :active_record def initialize(active_record) @active_record = active_record -- cgit v1.2.3 From aae3c3538492f19f1c4e1fcfe6c942ff72a30ce1 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 29 Nov 2010 10:58:21 -0800 Subject: removing interpolate_sql from join associations --- .../associations/class_methods/join_dependency/join_association.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index e7d1ffa9f2..3db80d341f 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -102,10 +102,6 @@ module ActiveRecord ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name end - def interpolate_sql(sql) - instance_eval("%@#{sql.gsub('@', '\@')}@", __FILE__, __LINE__) - end - private def allocate_aliases @@ -120,7 +116,7 @@ module ActiveRecord end def process_conditions(conditions, table_name) - Arel.sql(interpolate_sql(sanitize_sql(conditions, table_name))) + Arel.sql(sanitize_sql(conditions, table_name)) end def sanitize_sql(condition, table_name) -- cgit v1.2.3 From 10b1887a719588c1252906169f9d3d12ee1387c6 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 30 Nov 2010 17:48:10 -0800 Subject: JoinBase initialize can be deleted --- .../active_record/associations/class_methods/join_dependency.rb | 5 +++-- .../associations/class_methods/join_dependency/join_base.rb | 8 -------- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 6ab7bd0b06..c578845878 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -9,7 +9,8 @@ module ActiveRecord attr_reader :join_parts, :reflections, :table_aliases def initialize(base, associations, joins) - @join_parts = [JoinBase.new(base, joins)] + @table_joins = joins || '' + @join_parts = [JoinBase.new(base)] @associations = {} @reflections = [] @table_aliases = Hash.new(0) @@ -45,7 +46,7 @@ module ActiveRecord def count_aliases_from_table_joins(name) # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase quoted_name = join_base.active_record.connection.quote_table_name(name.downcase).downcase - join_sql = join_base.table_joins.to_s.downcase + join_sql = @table_joins.downcase join_sql.blank? ? 0 : # Table names join_sql.scan(/join(?:\s+\w+)?\s+#{quoted_name}\son/).size + diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb index ed05003f66..97003c1457 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb @@ -3,14 +3,6 @@ module ActiveRecord module ClassMethods class JoinDependency # :nodoc: class JoinBase < JoinPart # :nodoc: - # Extra joins provided when the JoinDependency was created - attr_reader :table_joins - - def initialize(active_record, joins = nil) - super(active_record) - @table_joins = joins - end - def ==(other) other.class == self.class && other.active_record == active_record -- cgit v1.2.3 From 0afebd5b31bdc6edc1399c77153e65f5ea156fe1 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 1 Dec 2010 18:00:24 -0800 Subject: no need for self --- .../associations/class_methods/join_dependency/join_association.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 3db80d341f..4dd11a7366 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -52,7 +52,7 @@ module ActiveRecord def find_parent_in(other_join_dependency) other_join_dependency.join_parts.detect do |join_part| - self.parent == join_part + parent == join_part end end -- cgit v1.2.3 From 15633519f7fbe5450e4b232e556deca3340eb88d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 2 Dec 2010 13:53:59 -0800 Subject: removing some calls to insert on arel --- .../associations/has_and_belongs_to_many_association.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index f6f291a039..367104ec1b 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -49,7 +49,7 @@ module ActiveRecord timestamps = record_timestamp_columns(record) timezone = record.send(:current_time_from_proper_timezone) if timestamps.any? - attributes = Hash[columns.map do |column| + attributes = columns.map do |column| name = column.name value = case name.to_s when @reflection.primary_key_name.to_s @@ -62,9 +62,10 @@ module ActiveRecord @owner.send(:quote_value, record[name], column) if record.has_attribute?(name) end [relation[name], value] unless value.nil? - end] + end - relation.insert(attributes) + stmt = relation.compile_insert Hash[attributes] + @owner.connection.insert stmt.to_sql end true -- cgit v1.2.3 From ead0c6eed35c71cc990f8c5b6d98e20c6072c136 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 2 Dec 2010 14:49:02 -0800 Subject: removing more calls to deprecated methods --- activerecord/lib/active_record/associations/has_many_association.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 685d818ab3..4ff61fff45 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -67,9 +67,10 @@ module ActiveRecord @reflection.klass.delete(records.map { |record| record.id }) else relation = Arel::Table.new(@reflection.table_name) - relation.where(relation[@reflection.primary_key_name].eq(@owner.id). + stmt = relation.where(relation[@reflection.primary_key_name].eq(@owner.id). and(relation[@reflection.klass.primary_key].in(records.map { |r| r.id })) - ).update(relation[@reflection.primary_key_name] => nil) + ).compile_update(relation[@reflection.primary_key_name] => nil) + @owner.connection.update stmt.to_sql @owner.class.update_counters(@owner.id, cached_counter_attribute_name => -records.size) if has_cached_counter? end -- cgit v1.2.3 From 9a3e29e126d9daf6175b4d2be50112d1c8771d17 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 2 Dec 2010 15:56:55 -0800 Subject: remove calls to deprecated methods --- .../associations/has_and_belongs_to_many_association.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index 367104ec1b..e2ce9aefcf 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -76,9 +76,10 @@ module ActiveRecord records.each { |record| @owner.connection.delete(interpolate_sql(sql, record)) } else relation = Arel::Table.new(@reflection.options[:join_table]) - relation.where(relation[@reflection.primary_key_name].eq(@owner.id). + stmt = relation.where(relation[@reflection.primary_key_name].eq(@owner.id). and(relation[@reflection.association_foreign_key].in(records.map { |x| x.id }.compact)) - ).delete + ).compile_delete + @owner.connection.delete stmt.to_sql end end -- cgit v1.2.3 From ef79658bd143a9243eefa90db2f9ce300f18dd0d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 7 Dec 2010 14:47:21 -0800 Subject: save the AR reference rather than delegating --- .../active_record/associations/class_methods/join_dependency.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index c578845878..9f171f891d 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -6,9 +6,10 @@ module ActiveRecord module Associations module ClassMethods class JoinDependency # :nodoc: - attr_reader :join_parts, :reflections, :table_aliases + attr_reader :join_parts, :reflections, :table_aliases, :active_record def initialize(base, associations, joins) + @active_record = base @table_joins = joins || '' @join_parts = [JoinBase.new(base)] @associations = {} @@ -45,7 +46,7 @@ module ActiveRecord def count_aliases_from_table_joins(name) # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase - quoted_name = join_base.active_record.connection.quote_table_name(name.downcase).downcase + quoted_name = active_record.connection.quote_table_name(name.downcase).downcase join_sql = @table_joins.downcase join_sql.blank? ? 0 : # Table names @@ -61,11 +62,11 @@ module ActiveRecord records = rows.map { |model| primary_id = model[primary_key] parent = parents[primary_id] ||= join_base.instantiate(model) - construct(parent, @associations, join_associations.dup, model) + construct(parent, @associations, join_associations, model) parent }.uniq - remove_duplicate_results!(join_base.active_record, records, @associations) + remove_duplicate_results!(active_record, records, @associations) records end -- cgit v1.2.3 From ddbd2039615ca4376a46a97a17612732f24568cd Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 7 Dec 2010 15:23:29 -0800 Subject: reduce string objects, reduce method calls --- .../active_record/associations/class_methods/join_dependency.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 9f171f891d..34928bc764 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -10,7 +10,7 @@ module ActiveRecord def initialize(base, associations, joins) @active_record = base - @table_joins = joins || '' + @table_joins = joins @join_parts = [JoinBase.new(base)] @associations = {} @reflections = [] @@ -45,12 +45,13 @@ module ActiveRecord end def count_aliases_from_table_joins(name) + return 0 unless @table_joins + # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase quoted_name = active_record.connection.quote_table_name(name.downcase).downcase join_sql = @table_joins.downcase - join_sql.blank? ? 0 : - # Table names - join_sql.scan(/join(?:\s+\w+)?\s+#{quoted_name}\son/).size + + # Table names + join_sql.scan(/join(?:\s+\w+)?\s+#{quoted_name}\son/).size + # Table aliases join_sql.scan(/join(?:\s+\w+)?\s+\S+\s+#{quoted_name}\son/).size end -- cgit v1.2.3 From d6133209ce54bac430e63ec512251eae182b79e1 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 7 Dec 2010 15:23:50 -0800 Subject: arel is lazy about column information, so no need to pass it around --- .../associations/class_methods/join_dependency/join_base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb index 97003c1457..67567f06df 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_base.rb @@ -13,7 +13,7 @@ module ActiveRecord end def table - Arel::Table.new(table_name, :engine => arel_engine, :columns => active_record.columns) + Arel::Table.new(table_name, arel_engine) end def aliased_table_name -- cgit v1.2.3 From 2d9d6cd4c263f639adf8e26c7d95e7772e0c4eb7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 7 Dec 2010 16:48:59 -0800 Subject: passing the ast to JoinDependency --- .../associations/class_methods/join_dependency.rb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 34928bc764..86d43f21d3 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -45,11 +45,20 @@ module ActiveRecord end def count_aliases_from_table_joins(name) - return 0 unless @table_joins + return 0 if !@table_joins || Arel::Table === @table_joins + return count_aliases_from_string(@table_joins.downcase, name) if String === @table_joins + + @table_joins.grep(Arel::Table).find_all { |table| + table.name.downcase == name + }.length + @table_joins.grep(String).map { |s| + count_aliases_from_string(s, name) + }.sum + end + + def count_aliases_from_string(join_sql, name) # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase quoted_name = active_record.connection.quote_table_name(name.downcase).downcase - join_sql = @table_joins.downcase # Table names join_sql.scan(/join(?:\s+\w+)?\s+#{quoted_name}\son/).size + # Table aliases -- cgit v1.2.3 From d98cb5153dad97cde82ec91a1993043cfa9bc0e4 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 7 Dec 2010 17:05:15 -0800 Subject: JoinDependency is always created with an AST now --- .../associations/class_methods/join_dependency.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 86d43f21d3..928e8152a5 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -49,10 +49,16 @@ module ActiveRecord return count_aliases_from_string(@table_joins.downcase, name) if String === @table_joins - @table_joins.grep(Arel::Table).find_all { |table| - table.name.downcase == name - }.length + @table_joins.grep(String).map { |s| - count_aliases_from_string(s, name) + @table_joins.grep(Arel::Nodes::Join).map { |join| + right = join.right + case right + when Arel::Table + right.name.downcase == name ? 1 : 0 + when String + count_aliases_from_string(right.downcase, name) + else + 0 + end }.sum end -- cgit v1.2.3 From 1d96d44da318faab8d213f330aebcecdbec52f5d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 7 Dec 2010 18:54:04 -0800 Subject: passing the ast to a table when the relation is a table --- .../lib/active_record/associations/class_methods/join_dependency.rb | 2 -- 1 file changed, 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 928e8152a5..d508c3b7aa 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -47,8 +47,6 @@ module ActiveRecord def count_aliases_from_table_joins(name) return 0 if !@table_joins || Arel::Table === @table_joins - return count_aliases_from_string(@table_joins.downcase, name) if String === @table_joins - @table_joins.grep(Arel::Nodes::Join).map { |join| right = join.right case right -- cgit v1.2.3 From f4223cc7abeeae5f4849eab27951faa55f3c6996 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Dec 2010 11:18:26 -0800 Subject: arel ignores the columns parameter --- .../associations/class_methods/join_dependency/join_association.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 4dd11a7366..2c20e304d0 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -67,8 +67,7 @@ module ActiveRecord def table @table ||= Arel::Table.new( - table_name, :as => aliased_table_name, - :engine => arel_engine, :columns => active_record.columns + table_name, :as => aliased_table_name, :engine => arel_engine ) end -- cgit v1.2.3 From b8d57a0400f95abe1b87634e9cada8868ff0a22e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Dec 2010 11:50:16 -0800 Subject: have table_aliases call count_aliases to set the default value --- .../lib/active_record/associations/class_methods/join_dependency.rb | 4 +++- .../associations/class_methods/join_dependency/join_association.rb | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index d508c3b7aa..13576e1aec 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -14,7 +14,9 @@ module ActiveRecord @join_parts = [JoinBase.new(base)] @associations = {} @reflections = [] - @table_aliases = Hash.new(0) + @table_aliases = Hash.new do |h,name| + h[name] = count_aliases_from_table_joins(name) + end @table_aliases[base.table_name] = 1 build(associations) end diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 2c20e304d0..15c1e7de55 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -77,10 +77,6 @@ module ActiveRecord protected def aliased_table_name_for(name, suffix = nil) - if @join_dependency.table_aliases[name].zero? - @join_dependency.table_aliases[name] = @join_dependency.count_aliases_from_table_joins(name) - end - if !@join_dependency.table_aliases[name].zero? # We need an alias name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}" @join_dependency.table_aliases[name] += 1 -- cgit v1.2.3 From de4bd472c3298f0455de8e3862c31900184f3c31 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Dec 2010 11:54:45 -0800 Subject: remove code that could never be executed --- .../associations/class_methods/join_dependency/join_association.rb | 4 ---- 1 file changed, 4 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 15c1e7de55..9c43e9edd7 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -80,10 +80,6 @@ module ActiveRecord if !@join_dependency.table_aliases[name].zero? # We need an alias name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}" @join_dependency.table_aliases[name] += 1 - if @join_dependency.table_aliases[name] == 1 # First time we've seen this name - # Also need to count the aliases from the table_aliases to avoid incorrect count - @join_dependency.table_aliases[name] += @join_dependency.count_aliases_from_table_joins(name) - end table_index = @join_dependency.table_aliases[name] name = name[0..active_record.connection.table_alias_length-3] + "_#{table_index}" if table_index > 1 else -- cgit v1.2.3 From dcc0c9a8bb49d956476a7165f3eef6699ec4628b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Dec 2010 12:05:02 -0800 Subject: dry up calls to table_aliases --- .../class_methods/join_dependency/join_association.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 9c43e9edd7..bf0190e40a 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -77,13 +77,15 @@ module ActiveRecord protected def aliased_table_name_for(name, suffix = nil) - if !@join_dependency.table_aliases[name].zero? # We need an alias + aliases = @join_dependency.table_aliases + + if !aliases[name].zero? # We need an alias name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}" - @join_dependency.table_aliases[name] += 1 - table_index = @join_dependency.table_aliases[name] + aliases[name] += 1 + table_index = aliases[name] name = name[0..active_record.connection.table_alias_length-3] + "_#{table_index}" if table_index > 1 else - @join_dependency.table_aliases[name] += 1 + aliases[name] += 1 end name -- cgit v1.2.3 From c69bd59a9cc7c0de3d6db7f8c90e73778516debf Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Dec 2010 12:09:00 -0800 Subject: only call active_record once --- .../associations/class_methods/join_dependency/join_association.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index bf0190e40a..09094f3ed5 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -80,10 +80,12 @@ module ActiveRecord aliases = @join_dependency.table_aliases if !aliases[name].zero? # We need an alias - name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}" + connection = active_record.connection + + name = connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}" aliases[name] += 1 table_index = aliases[name] - name = name[0..active_record.connection.table_alias_length-3] + "_#{table_index}" if table_index > 1 + name = name[0, connection.table_alias_length-3] + "_#{table_index}" if table_index > 1 else aliases[name] += 1 end -- cgit v1.2.3 From 45ea60eee7e6284768b78d51dbed4a2913aa18dd Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Dec 2010 12:11:43 -0800 Subject: fewer method calls, fewer code branches --- .../class_methods/join_dependency/join_association.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 09094f3ed5..25511a092f 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -79,17 +79,16 @@ module ActiveRecord def aliased_table_name_for(name, suffix = nil) aliases = @join_dependency.table_aliases - if !aliases[name].zero? # We need an alias + if aliases[name] != 0 # We need an alias connection = active_record.connection name = connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}" - aliases[name] += 1 - table_index = aliases[name] + table_index = aliases[name] + 1 name = name[0, connection.table_alias_length-3] + "_#{table_index}" if table_index > 1 - else - aliases[name] += 1 end + aliases[name] += 1 + name end -- cgit v1.2.3 From e924814b28d655242a49f543cf453d55712071b1 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Dec 2010 13:40:10 -0800 Subject: just allocate the table in initialize --- .../class_methods/join_dependency/join_association.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 25511a092f..b063d927b9 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -42,6 +42,9 @@ module ActiveRecord # depends on the state of the join dependency, but we want it to work the same way # every time. allocate_aliases + @table = Arel::Table.new( + table_name, :as => aliased_table_name, :engine => arel_engine + ) end def ==(other) @@ -65,12 +68,7 @@ module ActiveRecord joining_relation.joins(self) end - def table - @table ||= Arel::Table.new( - table_name, :as => aliased_table_name, :engine => arel_engine - ) - end - + attr_reader :table # More semantic name given we are talking about associations alias_method :target_table, :table -- cgit v1.2.3 From 07b0e59988beb1b29bdfadd02f0d015eae9191cf Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 Dec 2010 17:31:20 -0800 Subject: use sort_by --- .../lib/active_record/associations/class_methods/join_dependency.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 13576e1aec..1856395f2d 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -151,7 +151,7 @@ module ActiveRecord build(association, parent, join_type) end when Hash - associations.keys.sort{|a,b|a.to_s<=>b.to_s}.each do |name| + associations.keys.sort_by { |a| a.to_s }.each do |name| join_association = build(name, parent, join_type) build(associations[name], join_association, join_type) end -- cgit v1.2.3 From 3cbf5d9794cc49783fcbcb160cdd908981ee8f84 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 Dec 2010 11:13:00 -0800 Subject: removing useless lasgn --- .../associations/class_methods/join_dependency/join_association.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index b063d927b9..024ce4114b 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -136,7 +136,7 @@ module ActiveRecord conditions << process_conditions(options[:conditions], aliased_table_name) end - relation = relation.on(*conditions) + relation.on(*conditions) end def join_has_and_belongs_to_many_to(relation) -- cgit v1.2.3 From 12f67a70697212b55cde66f89ccd4caf0e9f4dad Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 Dec 2010 15:31:09 -0800 Subject: use inject rather than lasgn --- .../class_methods/join_dependency/join_association.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 024ce4114b..5e37542416 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -121,14 +121,13 @@ module ActiveRecord # If the target table is an STI model then we must be sure to only include records of # its type and its sub-types. unless active_record.descends_from_active_record? - sti_column = target_table[active_record.inheritance_column] - + sti_column = target_table[active_record.inheritance_column] + subclasses = active_record.descendants sti_condition = sti_column.eq(active_record.sti_name) - active_record.descendants.each do |subclass| - sti_condition = sti_condition.or(sti_column.eq(subclass.sti_name)) - end - conditions << sti_condition + conditions << subclasses.inject(sti_condition) { |attr,subclass| + attr.or(sti_column.eq(subclass.sti_name)) + } end # If the reflection has conditions, add them -- cgit v1.2.3 From 06ba9eaa62f756b70217f4d1e277c37e835343d4 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 Dec 2010 15:54:07 -0800 Subject: move join creation a little closer to where it is used --- .../associations/class_methods/join_dependency/join_association.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 5e37542416..b0091c613d 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -116,8 +116,6 @@ module ActiveRecord end def join_target_table(relation, *conditions) - relation = relation.join(target_table, join_type) - # If the target table is an STI model then we must be sure to only include records of # its type and its sub-types. unless active_record.descends_from_active_record? @@ -135,7 +133,9 @@ module ActiveRecord conditions << process_conditions(options[:conditions], aliased_table_name) end - relation.on(*conditions) + join = relation.join(target_table, join_type) + + join.on(*conditions) end def join_has_and_belongs_to_many_to(relation) -- cgit v1.2.3 From 6e15a7fa3c42e183541a893196d83a83cfc20553 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 Dec 2010 11:46:02 -0800 Subject: only quote the table name once per call --- .../associations/class_methods/join_dependency.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 1856395f2d..b6d85a7c7d 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -15,7 +15,7 @@ module ActiveRecord @associations = {} @reflections = [] @table_aliases = Hash.new do |h,name| - h[name] = count_aliases_from_table_joins(name) + h[name] = count_aliases_from_table_joins(name.downcase) end @table_aliases[base.table_name] = 1 build(associations) @@ -49,13 +49,16 @@ module ActiveRecord def count_aliases_from_table_joins(name) return 0 if !@table_joins || Arel::Table === @table_joins + # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase + quoted_name = active_record.connection.quote_table_name(name).downcase + @table_joins.grep(Arel::Nodes::Join).map { |join| right = join.right case right when Arel::Table right.name.downcase == name ? 1 : 0 when String - count_aliases_from_string(right.downcase, name) + count_aliases_from_string(right.downcase, quoted_name) else 0 end @@ -63,12 +66,10 @@ module ActiveRecord end def count_aliases_from_string(join_sql, name) - # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase - quoted_name = active_record.connection.quote_table_name(name.downcase).downcase # Table names - join_sql.scan(/join(?:\s+\w+)?\s+#{quoted_name}\son/).size + + join_sql.scan(/join(?:\s+\w+)?\s+#{name}\son/).size + # Table aliases - join_sql.scan(/join(?:\s+\w+)?\s+\S+\s+#{quoted_name}\son/).size + join_sql.scan(/join(?:\s+\w+)?\s+\S+\s+#{name}\son/).size end def instantiate(rows) -- cgit v1.2.3 From 73d4d6704ec2a5b11e32d7f421f4614ac83d8384 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 Dec 2010 13:20:03 -0800 Subject: avoid *args on join_target_table --- .../class_methods/join_dependency/join_association.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index b0091c613d..5c062e874e 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -115,7 +115,9 @@ module ActiveRecord active_record.send(:sanitize_sql, condition, table_name) end - def join_target_table(relation, *conditions) + def join_target_table(relation, condition) + conditions = [condition] + # If the target table is an STI model then we must be sure to only include records of # its type and its sub-types. unless active_record.descends_from_active_record? @@ -247,9 +249,9 @@ module ActiveRecord join_target_table( relation, target_table["#{reflection.options[:as]}_id"]. - eq(parent_table[parent.primary_key]), + eq(parent_table[parent.primary_key]).and( target_table["#{reflection.options[:as]}_type"]. - eq(parent.active_record.base_class.name) + eq(parent.active_record.base_class.name)) ) end -- cgit v1.2.3 From f528389a5580227f4d173bf4915a98b71befb32e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 Dec 2010 13:26:58 -0800 Subject: use alias nodes to represent table aliases --- .../associations/class_methods/join_dependency/join_association.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 5c062e874e..ff6a9993b0 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -142,9 +142,8 @@ module ActiveRecord def join_has_and_belongs_to_many_to(relation) join_table = Arel::Table.new( - options[:join_table], :engine => arel_engine, - :as => @aliased_join_table_name - ) + options[:join_table] + ).alias(@aliased_join_table_name) fk = options[:foreign_key] || reflection.active_record.to_s.foreign_key klass_fk = options[:association_foreign_key] || reflection.klass.to_s.foreign_key -- cgit v1.2.3 From e07772556a2167e44158f367beb3a45e6a55671f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 Dec 2010 13:28:50 -0800 Subject: use table alias nodes rather than Table nodes --- .../associations/class_methods/join_dependency/join_association.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index ff6a9993b0..98536d23bc 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -181,9 +181,8 @@ module ActiveRecord def join_has_many_through_to(relation) join_table = Arel::Table.new( - through_reflection.klass.table_name, :engine => arel_engine, - :as => @aliased_join_table_name - ) + through_reflection.klass.table_name + ).alias @aliased_join_table_name jt_conditions = [] jt_foreign_key = first_key = second_key = nil -- cgit v1.2.3 From 0042054ea873a8d25d9bbdc4c7fe0febe1b76042 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 Dec 2010 14:44:42 -0800 Subject: remove lasgn since AST is mutated --- .../class_methods/join_dependency/join_association.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 98536d23bc..4839068f6d 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -135,9 +135,15 @@ module ActiveRecord conditions << process_conditions(options[:conditions], aliased_table_name) end - join = relation.join(target_table, join_type) + ands = relation.create_and(conditions) - join.on(*conditions) + join = relation.create_join( + relation.froms.first, + target_table, + relation.create_on(ands), + join_type) + + relation.from join end def join_has_and_belongs_to_many_to(relation) -- cgit v1.2.3 From b1447d902c39a4b324cb0dc54b80fecc0fe7e34e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 Dec 2010 15:13:51 -0800 Subject: explicitly set prefix --- .../associations/class_methods/join_dependency/join_association.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 4839068f6d..f1b923e98b 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -22,7 +22,7 @@ module ActiveRecord attr_reader :aliased_prefix, :aliased_table_name delegate :options, :through_reflection, :source_reflection, :to => :reflection - delegate :table, :table_name, :to => :parent, :prefix => true + delegate :table, :table_name, :to => :parent, :prefix => :parent def initialize(reflection, join_dependency, parent = nil) reflection.check_validity! -- cgit v1.2.3 From 59ec13155581918fe934890ff7d9e6c2c03dc92e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 Dec 2010 15:27:10 -0800 Subject: move ivar to initialize, use triple dot rather than minus --- .../associations/class_methods/join_dependency/join_association.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index f1b923e98b..c552603097 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -37,6 +37,7 @@ module ActiveRecord @join_dependency = join_dependency @parent = parent @join_type = Arel::InnerJoin + @aliased_prefix = "t#{ join_dependency.join_parts.size }" # This must be done eagerly upon initialisation because the alias which is produced # depends on the state of the join dependency, but we want it to work the same way @@ -97,7 +98,6 @@ module ActiveRecord private def allocate_aliases - @aliased_prefix = "t#{ join_dependency.join_parts.size }" @aliased_table_name = aliased_table_name_for(table_name) if reflection.macro == :has_and_belongs_to_many -- cgit v1.2.3 From 59bd9c2a3793febffb919f1555156208825d4a9c Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 Dec 2010 17:01:15 -0800 Subject: combine regexp --- .../lib/active_record/associations/class_methods/join_dependency.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index b6d85a7c7d..6be947df41 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -66,10 +66,8 @@ module ActiveRecord end def count_aliases_from_string(join_sql, name) - # Table names - join_sql.scan(/join(?:\s+\w+)?\s+#{name}\son/).size + - # Table aliases - join_sql.scan(/join(?:\s+\w+)?\s+\S+\s+#{name}\son/).size + # Table names + table aliases + join_sql.scan(/join(?:\s+\w+)?\s+(\S+\s+)?#{name}\son/).size end def instantiate(rows) -- cgit v1.2.3 From ad47b7bcc11aae7745b39354292b089ae18a8cfc Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 Dec 2010 17:03:32 -0800 Subject: just use the regexp directly --- .../associations/class_methods/join_dependency.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 6be947df41..5a0ff942ca 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -58,18 +58,16 @@ module ActiveRecord when Arel::Table right.name.downcase == name ? 1 : 0 when String - count_aliases_from_string(right.downcase, quoted_name) + # Table names + table aliases + right.downcase.scan( + /join(?:\s+\w+)?\s+(\S+\s+)?#{quoted_name}\son/ + ).size else 0 end }.sum end - def count_aliases_from_string(join_sql, name) - # Table names + table aliases - join_sql.scan(/join(?:\s+\w+)?\s+(\S+\s+)?#{name}\son/).size - end - def instantiate(rows) primary_key = join_base.aliased_primary_key parents = {} -- cgit v1.2.3 From c02fd2acc575f3e90da12d4915390a80a48b7c8e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 Dec 2010 11:25:47 -0800 Subject: taking advantage of the JoinSource node in the SQL AST --- .../associations/class_methods/join_dependency.rb | 20 ++++++-------------- .../join_dependency/join_association.rb | 1 - 2 files changed, 6 insertions(+), 15 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb index 5a0ff942ca..a74d0a4ca8 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency.rb @@ -47,24 +47,16 @@ module ActiveRecord end def count_aliases_from_table_joins(name) - return 0 if !@table_joins || Arel::Table === @table_joins + return 0 if Arel::Table === @table_joins # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase quoted_name = active_record.connection.quote_table_name(name).downcase - @table_joins.grep(Arel::Nodes::Join).map { |join| - right = join.right - case right - when Arel::Table - right.name.downcase == name ? 1 : 0 - when String - # Table names + table aliases - right.downcase.scan( - /join(?:\s+\w+)?\s+(\S+\s+)?#{quoted_name}\son/ - ).size - else - 0 - end + @table_joins.map { |join| + # Table names + table aliases + join.left.downcase.scan( + /join(?:\s+\w+)?\s+(\S+\s+)?#{quoted_name}\son/ + ).size }.sum end diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index c552603097..694778008b 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -138,7 +138,6 @@ module ActiveRecord ands = relation.create_and(conditions) join = relation.create_join( - relation.froms.first, target_table, relation.create_on(ands), join_type) -- cgit v1.2.3 From 80ff64a947b4acd3835faab36e3b7f44ade10170 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 Dec 2010 14:49:33 -0800 Subject: just copy the joins to the list --- .../lib/active_record/associations/has_many_through_association.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index d0c8af1801..6ad51e2fb4 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -54,7 +54,7 @@ module ActiveRecord end def construct_find_options!(options) - options[:joins] = construct_joins(options[:joins]) + options[:joins] = [construct_joins] + Array.wrap(options[:joins]) options[:include] = @reflection.source_reflection.options[:include] if options[:include].nil? && @reflection.source_reflection.options[:include] end -- cgit v1.2.3 From 18402b5d649658a4046769a6d74b76a6731f7c94 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 Dec 2010 14:57:03 -0800 Subject: supporting arel AST nodes when building join statements --- .../associations/through_association_scope.rb | 32 ++++++++++++---------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb index acddfda924..48386ee124 100644 --- a/activerecord/lib/active_record/associations/through_association_scope.rb +++ b/activerecord/lib/active_record/associations/through_association_scope.rb @@ -55,33 +55,35 @@ module ActiveRecord end def construct_joins(custom_joins = nil) - polymorphic_join = nil + right = @reflection.through_reflection.klass.arel_table + left = @reflection.klass.arel_table + + conditions = [] + if @reflection.source_reflection.macro == :belongs_to reflection_primary_key = @reflection.klass.primary_key source_primary_key = @reflection.source_reflection.primary_key_name if @reflection.options[:source_type] - polymorphic_join = "AND %s.%s = %s" % [ - @reflection.through_reflection.quoted_table_name, "#{@reflection.source_reflection.options[:foreign_type]}", - @owner.class.quote_value(@reflection.options[:source_type]) - ] + column = @reflection.source_reflection.options[:foreign_type] + conditions << + right[column].eq(@reflection.options[:source_type]) end else reflection_primary_key = @reflection.source_reflection.primary_key_name source_primary_key = @reflection.through_reflection.klass.primary_key if @reflection.source_reflection.options[:as] - polymorphic_join = "AND %s.%s = %s" % [ - @reflection.quoted_table_name, "#{@reflection.source_reflection.options[:as]}_type", - @owner.class.quote_value(@reflection.through_reflection.klass.name) - ] + column = "#{@reflection.source_reflection.options[:as]}_type" + conditions << + left[column].eq(@reflection.through_reflection.klass.name) end end - "INNER JOIN %s ON %s.%s = %s.%s %s #{@reflection.options[:joins]} #{custom_joins}" % [ - @reflection.through_reflection.quoted_table_name, - @reflection.quoted_table_name, reflection_primary_key, - @reflection.through_reflection.quoted_table_name, source_primary_key, - polymorphic_join - ] + conditions << + left[reflection_primary_key].eq(right[source_primary_key]) + + right.create_join( + right, + right.create_on(right.create_and(conditions))) end # Construct attributes for associate pointing to owner. -- cgit v1.2.3 From aa4d03fcfc42453b5553c001d24933365effe5f0 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 Dec 2010 15:03:06 -0800 Subject: construct_joins no longer needs an argument --- .../lib/active_record/associations/through_association_scope.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb index 48386ee124..f6b242168c 100644 --- a/activerecord/lib/active_record/associations/through_association_scope.rb +++ b/activerecord/lib/active_record/associations/through_association_scope.rb @@ -54,7 +54,7 @@ module ActiveRecord custom_select || @reflection.options[:select] || "#{distinct}#{@reflection.quoted_table_name}.*" end - def construct_joins(custom_joins = nil) + def construct_joins right = @reflection.through_reflection.klass.arel_table left = @reflection.klass.arel_table -- cgit v1.2.3 From 2f0708e97405fa55e641dd2eac8805f12f878f5a Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 Dec 2010 15:24:25 -0800 Subject: build SQL AST nodes rather than generate strings --- .../associations/through_association_scope.rb | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb index f6b242168c..8d701248af 100644 --- a/activerecord/lib/active_record/associations/through_association_scope.rb +++ b/activerecord/lib/active_record/associations/through_association_scope.rb @@ -23,25 +23,23 @@ module ActiveRecord # Build SQL conditions from attributes, qualified by table name. def construct_conditions - table_name = @reflection.through_reflection.quoted_table_name + table = @reflection.through_reflection.klass.arel_table conditions = construct_quoted_owner_attributes(@reflection.through_reflection).map do |attr, value| - "#{table_name}.#{attr} = #{value}" + table[attr].eq(value) end - conditions << sql_conditions if sql_conditions - "(" + conditions.join(') AND (') + ")" + conditions << Arel.sql(sql_conditions) if sql_conditions + table.create_and(conditions) end # Associate attributes pointing to owner, quoted. def construct_quoted_owner_attributes(reflection) if as = reflection.options[:as] - { "#{as}_id" => owner_quoted_id, - "#{as}_type" => reflection.klass.quote_value( - @owner.class.base_class.name.to_s, - reflection.klass.columns_hash["#{as}_type"]) } + { "#{as}_id" => @owner.id, + "#{as}_type" => @owner.class.base_class.name } elsif reflection.macro == :belongs_to - { reflection.klass.primary_key => @owner.class.quote_value(@owner[reflection.primary_key_name]) } + { reflection.klass.primary_key => @owner[reflection.primary_key_name] } else - { reflection.primary_key_name => owner_quoted_id } + { reflection.primary_key_name => @owner.id } end end -- cgit v1.2.3 From a64bf22a718bcc8d1a33234ab8a7cdd91c6d537b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 Dec 2010 15:27:06 -0800 Subject: class names are already strings, so we do not need to call to_s on the strings that are already strings --- .../lib/active_record/associations/through_association_scope.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb index 8d701248af..6b7faa9fc3 100644 --- a/activerecord/lib/active_record/associations/through_association_scope.rb +++ b/activerecord/lib/active_record/associations/through_association_scope.rb @@ -88,7 +88,7 @@ module ActiveRecord def construct_owner_attributes(reflection) if as = reflection.options[:as] { "#{as}_id" => @owner.id, - "#{as}_type" => @owner.class.base_class.name.to_s } + "#{as}_type" => @owner.class.base_class.name } else { reflection.primary_key_name => @owner.id } end @@ -102,7 +102,7 @@ module ActiveRecord join_attributes = construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id) if @reflection.options[:source_type] - join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name.to_s) + join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name) end if @reflection.through_reflection.options[:conditions].is_a?(Hash) -- cgit v1.2.3 From 5d37ff6bb2b1f948034bf06e450f2fdb8195c4e5 Mon Sep 17 00:00:00 2001 From: Ernie Miller Date: Mon, 3 May 2010 20:47:42 -0400 Subject: Fix hm:t to self table aliasing in construct_scope --- .../active_record/associations/through_association_scope.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb index 6b7faa9fc3..a55bf6323e 100644 --- a/activerecord/lib/active_record/associations/through_association_scope.rb +++ b/activerecord/lib/active_record/associations/through_association_scope.rb @@ -21,9 +21,17 @@ module ActiveRecord construct_owner_attributes(@reflection) end + def aliased_through_table + name = @reflection.through_reflection.table_name + + @reflection.table_name == name ? + @reflection.through_reflection.klass.arel_table.alias(name + "_join") : + @reflection.through_reflection.klass.arel_table + end + # Build SQL conditions from attributes, qualified by table name. def construct_conditions - table = @reflection.through_reflection.klass.arel_table + table = aliased_through_table conditions = construct_quoted_owner_attributes(@reflection.through_reflection).map do |attr, value| table[attr].eq(value) end @@ -53,7 +61,7 @@ module ActiveRecord end def construct_joins - right = @reflection.through_reflection.klass.arel_table + right = aliased_through_table left = @reflection.klass.arel_table conditions = [] -- cgit v1.2.3 From eba76640862d071d89c846f8624d1e651d872794 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Sun, 12 Dec 2010 16:35:27 +0000 Subject: Respect the default_scope on a join model when reading a through association --- .../lib/active_record/associations/has_many_through_association.rb | 2 +- .../lib/active_record/associations/has_one_through_association.rb | 2 +- .../lib/active_record/associations/through_association_scope.rb | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 6ad51e2fb4..781aa7ef62 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -81,7 +81,7 @@ module ActiveRecord def find_target return [] unless target_reflection_has_associated_record? - with_scope(@scope) { @reflection.klass.find(:all) } + scoped.all end def has_cached_counter? diff --git a/activerecord/lib/active_record/associations/has_one_through_association.rb b/activerecord/lib/active_record/associations/has_one_through_association.rb index 7f28abf464..e8cf73976b 100644 --- a/activerecord/lib/active_record/associations/has_one_through_association.rb +++ b/activerecord/lib/active_record/associations/has_one_through_association.rb @@ -33,7 +33,7 @@ module ActiveRecord private def find_target - with_scope(@scope) { @reflection.klass.find(:first) } + scoped.first end end end diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb index a55bf6323e..2ecd0f054a 100644 --- a/activerecord/lib/active_record/associations/through_association_scope.rb +++ b/activerecord/lib/active_record/associations/through_association_scope.rb @@ -3,6 +3,13 @@ module ActiveRecord module Associations module ThroughAssociationScope + def scoped + with_scope(@scope) do + @reflection.klass.scoped & + @reflection.through_reflection.klass.scoped + end + end + protected def construct_find_scope -- cgit v1.2.3 From 96bae30538951367a82235785e7dba3577b50a5a Mon Sep 17 00:00:00 2001 From: Pavel Gorbokon Date: Wed, 24 Nov 2010 10:17:49 +0200 Subject: Replace rudimentary named_scope with scope. [#6052 state:resolved] * rename method names (actually in tests) * rename instance variable @_named_scopes_cache to @_scopes_cache * rename references in doc comments * don't touch CHANGELOG :) --- .../active_record/associations/association_collection.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index abb17a11c6..11a7a725e5 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -102,7 +102,7 @@ module ActiveRecord def reset reset_target! - reset_named_scopes_cache! + reset_scopes_cache! @loaded = false end @@ -160,7 +160,7 @@ module ActiveRecord load_target delete(@target) reset_target! - reset_named_scopes_cache! + reset_scopes_cache! end # Calculate sum using SQL, not Enumerable @@ -253,7 +253,7 @@ module ActiveRecord load_target destroy(@target).tap do reset_target! - reset_named_scopes_cache! + reset_scopes_cache! end end @@ -409,9 +409,9 @@ module ActiveRecord if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method)) super elsif @reflection.klass.scopes[method] - @_named_scopes_cache ||= {} - @_named_scopes_cache[method] ||= {} - @_named_scopes_cache[method][args] ||= with_scope(@scope) { @reflection.klass.send(method, *args) } + @_scopes_cache ||= {} + @_scopes_cache[method] ||= {} + @_scopes_cache[method][args] ||= with_scope(@scope) { @reflection.klass.send(method, *args) } else with_scope(@scope) do if block_given? @@ -442,8 +442,8 @@ module ActiveRecord @target = Array.new end - def reset_named_scopes_cache! - @_named_scopes_cache = {} + def reset_scopes_cache! + @_scopes_cache = {} end def find_target -- cgit v1.2.3 From 14b880fd035fcdf807051398674c9aa89bd3b4d3 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Wed, 15 Dec 2010 23:27:15 +0000 Subject: Fix various issues with the :primary_key option in :through associations [#2421 state:resolved] --- .../associations/through_association_scope.rb | 26 ++++++++-------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'activerecord/lib/active_record/associations') diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb index 2ecd0f054a..5dc5b0c048 100644 --- a/activerecord/lib/active_record/associations/through_association_scope.rb +++ b/activerecord/lib/active_record/associations/through_association_scope.rb @@ -39,22 +39,22 @@ module ActiveRecord # Build SQL conditions from attributes, qualified by table name. def construct_conditions table = aliased_through_table - conditions = construct_quoted_owner_attributes(@reflection.through_reflection).map do |attr, value| + conditions = construct_owner_attributes(@reflection.through_reflection).map do |attr, value| table[attr].eq(value) end conditions << Arel.sql(sql_conditions) if sql_conditions table.create_and(conditions) end - # Associate attributes pointing to owner, quoted. - def construct_quoted_owner_attributes(reflection) + # Associate attributes pointing to owner + def construct_owner_attributes(reflection) if as = reflection.options[:as] - { "#{as}_id" => @owner.id, + { "#{as}_id" => @owner[reflection.active_record_primary_key], "#{as}_type" => @owner.class.base_class.name } elsif reflection.macro == :belongs_to { reflection.klass.primary_key => @owner[reflection.primary_key_name] } else - { reflection.primary_key_name => @owner.id } + { reflection.primary_key_name => @owner[reflection.active_record_primary_key] } end end @@ -74,7 +74,8 @@ module ActiveRecord conditions = [] if @reflection.source_reflection.macro == :belongs_to - reflection_primary_key = @reflection.klass.primary_key + reflection_primary_key = @reflection.source_reflection.options[:primary_key] || + @reflection.klass.primary_key source_primary_key = @reflection.source_reflection.primary_key_name if @reflection.options[:source_type] column = @reflection.source_reflection.options[:foreign_type] @@ -83,7 +84,8 @@ module ActiveRecord end else reflection_primary_key = @reflection.source_reflection.primary_key_name - source_primary_key = @reflection.through_reflection.klass.primary_key + source_primary_key = @reflection.source_reflection.options[:primary_key] || + @reflection.through_reflection.klass.primary_key if @reflection.source_reflection.options[:as] column = "#{@reflection.source_reflection.options[:as]}_type" conditions << @@ -99,16 +101,6 @@ module ActiveRecord right.create_on(right.create_and(conditions))) end - # Construct attributes for associate pointing to owner. - def construct_owner_attributes(reflection) - if as = reflection.options[:as] - { "#{as}_id" => @owner.id, - "#{as}_type" => @owner.class.base_class.name } - else - { reflection.primary_key_name => @owner.id } - end - end - # Construct attributes for :through pointing to owner and associate. def construct_join_attributes(associate) # TODO: revisit this to allow it for deletion, supposing dependent option is supported -- cgit v1.2.3