This project is archived and is in readonly mode.

#1220 ✓wontfix
Ben Johnson

Solving conflicted joins and include find options

Reported by Ben Johnson | October 15th, 2008 @ 08:45 PM | in 2.x

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.

Comments and changes to this ticket

  • Pratik

    Pratik January 18th, 2009 @ 06:37 AM

    • 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,
  • Ben Johnson

    Ben Johnson January 18th, 2009 @ 06:42 AM

    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?

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages