This project is archived and is in readonly mode.
named_scope buggy with has_many :through
Reported by Jérôme | October 16th, 2008 @ 01:27 PM | in 2.x
Hello,
I found named_scope is buggy with has_many :through when the 2 models do have the same column name used by the scope.
class User < AR::Base
has_many :friendships
has_many :friends, :class_name => 'User', :through => :friendships
end
class Friendship < AR::Base
belongs_to :user
belongs_to :friend, :class_name => 'User', :foreign_key => 'friend_id'
named_scope :pending, :conditions => { :state => 'pending' }
named_scope :accepted, :conditions => { :state => 'accepted' }
named_scope :denied, :conditions => { :state => 'denied' }
end
>> User.first.friendships.pending
=> []
# SELECT "users".* FROM "users" INNER JOIN friendships ON users.id = friendships.friend_id WHERE (("friendships".user_id = 1)) AND ("users"."state" = E'pending')
See ?
The SQL query takes "users"."state" instead of "friendships"."state".
Now the weirderst part:
class Friendship < AR::Base
belongs_to :user
belongs_to :friend, :class_name => 'User', :foreign_key => 'friend_id'
named_scope :pending, :conditions => { 'friendships.state' => 'pending' }
named_scope :accepted, :conditions => { 'friendships.state' => 'accepted' }
named_scope :denied, :conditions => { 'friendships.state' => 'denied' }
end
Declaring the table name in the :conditions hash doesn't change anything ! It still queries "users"."state" !
The only way I found to solve this issue is to double the friendships named_scope in the user model !!
class User < ActiveRecord::Base
has_many :friendships
has_many :friends, :class_name => 'User', :through => :friendships
named_scope :pending, :conditions => { 'friendships.state' => 'pending' }
named_scope :accepted, :conditions => { 'friendships.state' => 'accepted' }
named_scope :denied, :conditions => { 'friendships.state' => 'denied' }
end
of course the following will raise an error:
>> User.first.pending
but this call won't now:
>> User.first.friends.pending
=> [#<User id: 7701,... >]
Comments and changes to this ticket
-
Frederick Cheung December 21st, 2008 @ 10:49 PM
- Assigned user set to Frederick Cheung
- State changed from new to incomplete
I couldn't reproduce this with 2.1.2 or 2.2.2 or edge
I think you've skipped over a few steps. In the first bit you show a query selecting users.* going wrong but the corresponding bit of code you've shown you should be loading friendships, not users. Could your provide a more complete description of steps to reproduce ? (or even better, a failing test case)
-
Dennis Ushakov January 16th, 2009 @ 01:31 PM
Frederick, actually there's a bug in specification or in reflection code Spec says:
[:through]
Specifies a Join Model through which to perform the query. Options for :class_name and :foreign_key
are ignored, as the association uses the source reflection. You can only use a :through query through a belongs_to
or has_many association on the join model.
As we see here, :class_name should be ignored.
But in the source code we see: MacroReflection class in reflection.rb:
Returns the class name for the macro. For example, composed_of :balance, :class_name => 'Money' returns 'Money'
and has_many :clients returns 'Client'.
def class_name @class_name ||= options[:class_name] || derive_class_name end and no check for through attribute
-
Dennis Ushakov January 16th, 2009 @ 01:38 PM
Sorry for formatting issues. One addition. As I understand :source attribute should be used in this case, but it seems typo is dependent on this behaviour:
class Category < ActiveRecord::Base acts_as_list has_many :categorizations
has_many :articles,
:through => :categorizations, :order => "published_at DESC, created_at DESC"
has_many :published_articles,
:through => :categorizations, :class_name => 'Article', :conditions => { :published => true }, :order => "published_at DESC"
-
Prem Sichanugrist (sikachu) January 22nd, 2010 @ 08:52 AM
- State changed from incomplete to resolved
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>