Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #8937: habtm_with_joins_fix_with_name_checking.diff

File habtm_with_joins_fix_with_name_checking.diff, 1.8 kB (added by jcoglan, 3 years ago)
  • activerecord/lib/active_record/base.rb

    old new  
    11701170        # The optional scope argument is for the current :find scope. 
    11711171        def add_joins!(sql, options, scope = :auto) 
    11721172          scope = scope(:find) if :auto == scope 
    1173           join = (scope && scope[:joins]) || options[:joins] 
     1173          join = scope && scope[:joins] 
     1174          scope_tables = table_aliases_from_join_statement(join) 
     1175          if options[:joins] 
     1176            option_tables = table_aliases_from_join_statement(options[:joins]) 
     1177            join = "#{join.to_s} #{options[:joins]}" unless option_tables.map { |t| scope_tables.include?(t) }.include?(true) 
     1178          end 
    11741179          sql << " #{join} " if join 
    11751180        end 
    11761181 
     
    12021207          table_name 
    12031208        end 
    12041209 
     1210        # Returns the table names/aliases used in a JOIN SQL fragment. For each table used, 
     1211        # this method returns its alias if it is given one using AS, and its real name otherwise. 
     1212        def table_aliases_from_join_statement(str) 
     1213          return [] if str.blank? 
     1214          return str.scan(/JOIN\s+(`[^`]`|\S+)(?:\s+AS\s+(`[^`]`|\S+))?/i).collect do |name| 
     1215            (name[1] || name[0]).gsub(/^`(.*)`$/, '\1') 
     1216          end 
     1217        end 
     1218 
    12051219        # Enables dynamic finders like find_by_user_name(user_name) and find_by_user_name_and_password(user_name, password) that are turned into 
    12061220        # find(:first, :conditions => ["user_name = ?", user_name]) and  find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password]) 
    12071221        # respectively. Also works for find(:all), but using find_all_by_amount(50) that are turned into find(:all, :conditions => ["amount = ?", 50]).