Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Solving conflicted joins and include find options

#1220

Take this example:

User.all(:conditions => "orders.total > 100 and line_items.state = 'open'", :joins => {:orders => :line_items}, :include => :orders)

You get the same join being added twice. Plus, I may not want to eager load line items also. Why not skip any joins that have already been added? Now you can cherry pick which associations to eager load without getting an SQL error. I accomplished this by modifying the add_joins! function to the following:

def add_joins
scope = scope(:find) if :auto == scope
            merged_joins = scope && scope[:joins] && joins ? merge_joins(scope[:joins], joins) : (joins || scope && scope[:joins])
            case merged_joins
            when Symbol, Hash, Array
              if array_of_strings?(merged_joins)
                merged_joins.each { |merged_join| sql << " #{merged_join} " unless sql.include?(merged_join) }
              else
                join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil)
                join_dependency.join_associations.each do |assoc|
                  join_sql = assoc.association_join
                  sql << " #{join_sql} " unless sql.include?(join_sql)
                end
              end
            when String
              sql << " #{merged_joins} " if merged_joins && !sql.include?(merged_joins)
            end
end

This just makes more sense and allows the include option to be used as a way to eager load associations instead of a way to create joins, if that makes sense.

Reported by Ben Johnson · October 15th, 2008 @ 08:45 PM

State: wontfix
Milestone: 2.x
Assigned to: Frederick Cheung Frederick Cheung
Importance: none

Activity

  1. Pratik
    Pratik
    • State changed from new to wontfix
    • Assigned user set to Frederick Cheung

    You shouldn't really be using joins/include in the same query. One of the following should do the job :

    • Use only :include
    • Call preload_associations on the result array,

    January 18th, 2009 @ 06:37 AM

  2. Ben Johnson
    Ben Johnson

    I understand that, but I failed to specify the main reason this should be included. This can easily happen when chaining named scopes, since each scope can specify to eager load or join an association. Because of this they can easily clash. You already solve conflicts between the 2 when chaining named scope, why not solve them as a couple?

    January 18th, 2009 @ 06:42 AM