Hi there, I''ve recently started using the :through option on has_many associations and for the most part I''ve had no issues, but I''ve seemed to run into a bit of a roadblock with a specific case outlined below. I''m not sure if this is a bug in the feature or simply lack of user understandings. Anyway, here''s my scenario: I have 3 classes for the join. Showing just the one side of the join with the 2 classes (the 3rd class is called User)... class PlayerStatistic < ActiveRecord::Base belongs_to :game belongs_to :user end class Game < ActiveRecord::Base has_many :statistics, :class_name => ''PlayerStatistic'' has_many :players, :through => :statistics, :class_name => ''User'' end I can do.. g = Game.find(:first) g.statistics g.players g.statistics[0].user as expected. Now if I change the name of my association from user to player... class PlayerStatistic < ActiveRecord::Base belongs_to :game belongs_to :player, :class_name => ''User'' # <-- this line different end # still the same code as above class Game < ActiveRecord::Base has_many :statistics, :class_name => ''PlayerStatistic'' has_many :players, :through => :statistics, :class_name => ''User'' end I can do.. g = Game.find(:first) g.statistics g.statistics[0].player # player now instead of user works but no longer can call.. g.players This fails with a ActiveRecord::HasManyThroughSourceAssociationNotFoundError exception. Is this a bug or am I simply missing something here? Thanks, Andrew
Andrew Kaspick wrote:> Now if I change the name of my association from user to player... > > class PlayerStatistic < ActiveRecord::Base > belongs_to :game > belongs_to :player, :class_name => ''User'' # <-- this line different > end > > # still the same code as above > class Game < ActiveRecord::Base > has_many :statistics, :class_name => ''PlayerStatistic'' > has_many :players, :through => :statistics, > :class_name => ''User'' > end > > I can do.. > g = Game.find(:first) > g.statistics > g.statistics[0].player # player now instead of user works > > but no longer can call.. > g.players > > This fails with a > ActiveRecord::HasManyThroughSourceAssociationNotFoundError exception. > > Is this a bug or am I simply missing something here?Andrew, for this example you should leave the class_name option off the through association declaration. The class_name option for through assocations is really a source_association_name option. The correct class of the associated objects is picked up from the class of the source belongs_to association. This will definitely confuse a lot of people unless either the special use of class_name is documented, or the class_name option is made invalid on through associations and replaced with a source_association_name option. Mark
Alright, what you suggested works pefectly. As you said, I found this confusing. I had things working fine in my first case and then decided to do my rename in the join table and then things stopped working. Of course my first thoughts are to look for the problem in the join table where I made the change. I''m sure if you made one of the changes suggested, that would save others from the same headache. Documentation works, but sometimes the really fine details of it can be glossed over unfortunately and I would have to think that removing the confusion via your source suggestion would be a nicer option. On 3/22/06, Mark James <mrj@bigpond.net.au> wrote:> Andrew Kaspick wrote: > > > Now if I change the name of my association from user to player... > > > > class PlayerStatistic < ActiveRecord::Base > > belongs_to :game > > belongs_to :player, :class_name => ''User'' # <-- this line different > > end > > > > # still the same code as above > > class Game < ActiveRecord::Base > > has_many :statistics, :class_name => ''PlayerStatistic'' > > has_many :players, :through => :statistics, > > :class_name => ''User'' > > end > > > > I can do.. > > g = Game.find(:first) > > g.statistics > > g.statistics[0].player # player now instead of user works > > > > but no longer can call.. > > g.players > > > > This fails with a > > ActiveRecord::HasManyThroughSourceAssociationNotFoundError exception. > > > > Is this a bug or am I simply missing something here? > > Andrew, for this example you should leave the class_name option > off the through association declaration. The class_name option > for through assocations is really a source_association_name option. > The correct class of the associated objects is picked up from the > class of the source belongs_to association. > > This will definitely confuse a lot of people unless either > the special use of class_name is documented, or the class_name > option is made invalid on through associations and replaced with > a source_association_name option. > > Mark > _______________________________________________ > Rails-core mailing list > Rails-core@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-core >
Another thought is improving the message returned from the exception to give a better hint as to why the error is occuring. On 3/22/06, Andrew Kaspick <akaspick@gmail.com> wrote:> Alright, what you suggested works pefectly. > > As you said, I found this confusing. I had things working fine in my > first case and then decided to do my rename in the join table and then > things stopped working. Of course my first thoughts are to look for > the problem in the join table where I made the change. > > I''m sure if you made one of the changes suggested, that would save > others from the same headache. Documentation works, but sometimes the > really fine details of it can be glossed over unfortunately and I > would have to think that removing the confusion via your source > suggestion would be a nicer option. > > On 3/22/06, Mark James <mrj@bigpond.net.au> wrote: > > Andrew Kaspick wrote: > > > > > Now if I change the name of my association from user to player... > > > > > > class PlayerStatistic < ActiveRecord::Base > > > belongs_to :game > > > belongs_to :player, :class_name => ''User'' # <-- this line different > > > end > > > > > > # still the same code as above > > > class Game < ActiveRecord::Base > > > has_many :statistics, :class_name => ''PlayerStatistic'' > > > has_many :players, :through => :statistics, > > > :class_name => ''User'' > > > end > > > > > > I can do.. > > > g = Game.find(:first) > > > g.statistics > > > g.statistics[0].player # player now instead of user works > > > > > > but no longer can call.. > > > g.players > > > > > > This fails with a > > > ActiveRecord::HasManyThroughSourceAssociationNotFoundError exception. > > > > > > Is this a bug or am I simply missing something here? > > > > Andrew, for this example you should leave the class_name option > > off the through association declaration. The class_name option > > for through assocations is really a source_association_name option. > > The correct class of the associated objects is picked up from the > > class of the source belongs_to association. > > > > This will definitely confuse a lot of people unless either > > the special use of class_name is documented, or the class_name > > option is made invalid on through associations and replaced with > > a source_association_name option. > > > > Mark > > _______________________________________________ > > Rails-core mailing list > > Rails-core@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails-core > > >