Bug rails activerecord association join


#1

hi,
I found a bug in ActiveRecord association SQL INNER JOIN codes. in
has_many, has_one, habtm and belongs_to queries the foreign key is
determined from the table name of reflection and self. but that’s
worng because if you use a global prefix or suffix for your tables the
foreign keys will be in format of PREFIX_CLASSNAME_SUFFIX_id which is
wrong, because it breaks the advantage of changing the prefix and
giving it a go without chanigng any field names… on the other hand
the associations lik @blog.comments work just normal (using
CLASSNAME_id). I fixed the problem by changing the determination of
foreign key from table name to class name as following.

I removed table_name references and replaced them with to_s’s to get
class names… I thought of using class_name method but it gives the
parent class’s name in STI (I dont know if its the desired behaviour
or is it also a bug)

Is there a better way of doing this? I wanna submit a patch but
couldnt be sure if I did it correct.

module ActiveRecord
module Associations
def self.append_features(base)
super
base.extend(ClassMethods)
end

module ClassMethods
private
def association_join(reflection)
      case reflection.macro
        when :has_and_belongs_to_many
          " LEFT OUTER JOIN #{reflection.options[:join_table]} ON " 
  •         "#{reflection.options[:join_table]}.#{reflection.options[:foreign_key]
    

|| to_s.foreign_key} = " +
"#{table_name}.#{primary_key} " +
" LEFT OUTER JOIN #{reflection.klass.table_name} ON " +
"#{reflection.options[:join_table]}.#{reflection.options[:association_foreign_key]
|| reflection.klass.to_s.foreign_key} = " +
"#{reflection.klass.table_name}.#{reflection.klass.primary_key}
"
when :has_many, :has_one
" LEFT OUTER JOIN #{reflection.klass.table_name} ON " +
"#{reflection.klass.table_name}.#{reflection.options[:foreign_key]
|| to_s.foreign_key} = " +
"#{table_name}.#{primary_key} "
when :belongs_to
" LEFT OUTER JOIN #{reflection.klass.table_name} ON " +
"#{reflection.klass.table_name}.#{reflection.klass.primary_key}
= " +
"#{table_name}.#{reflection.options[:foreign_key] ||
reflection.klass.to_s.foreign_key} "
else
“”
end
end
end
end
end