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

Ticket #9851 (reopened enhancement)

Opened 2 years ago

Last modified 2 years ago

has_many :through broken for belongs_to on 2.0 preview

Reported by: albus522 Assigned to: core
Priority: normal Milestone: 2.x
Component: ActiveRecord Version: edge
Severity: normal Keywords:
Cc:

Description

Here is what I am trying to do class App < ActiveRecord::Base

belongs_to :client has_many :users, :through => :client

end class Client < ActiveRecord::Base

has_many :apps has_many :users

end class User < ActiveRecord::Base

belongs_to :client

end

This doesn't work it tries to do "WHERE clients.client_id = #{app.id}" when it should do "WHERE clients.id = #{app.client_id}" Please help

Attachments

has_many_through_association.rb.diff (0.7 kB) - added by albus522 on 10/12/07 15:18:32.
active_record_7892.diff (13.9 kB) - added by albus522 on 10/15/07 01:29:36.
Diff against trunk/activerecord revision 7892
active_record_7917.diff (13.4 kB) - added by albus522 on 10/15/07 13:17:32.
Diff against trunk/activerecord revision 7917

Change History

10/12/07 15:18:32 changed by albus522

  • attachment has_many_through_association.rb.diff added.

10/12/07 15:20:16 changed by albus522

I figured out how to fix the issue and have attached a patch for the file activerecord/lib/active_record/associations/has_many_through_association.rb

10/12/07 15:33:21 changed by hasmanyjosh

  • status changed from new to closed.
  • resolution set to invalid.

This is not a defect. You are just using the associations incorrectly. has_many :through can only go through a has_many association, not a belongs_to. Please read the association docs or take this to the email list - Trac is not a support forum.

10/12/07 15:46:04 changed by albus522

  • status changed from closed to reopened.
  • type changed from defect to enhancement.
  • resolution deleted.

I would then like to reopen this ticket as an enhancement since I have already done the work. This should be a valid use for a has_many :through association. There is no reason that the only use has to be a replacements for a has_and_belongs_to_many with join table attributes.

10/12/07 15:53:53 changed by technoweenie

On the surface it looks fine, but what's wrong with either of these approaches?

class App < ActiveRecord::Base
  belongs_to :client
  delegate :users, :to => :client
end

@app.client.users
@app.users # using delegation

More cases to associations add a lot more complexity, and I just don't think it's worth it in this case just to save a single primary-key indexed SQL query.

10/12/07 16:00:36 changed by hasmanyjosh

  • status changed from reopened to closed.
  • resolution set to incomplete.

There's a lot more work that needs to be done to submit this as an enhancement patch. You need a full set of test cases for the new functionality. You also need to update the association documentation. And I suspect there will need to be other code changes to work with features like eager loading and using << to create the join model objects.

As Rick showed above, there are simple alternatives that get you most of what you want. I agree that adding complexity to the association code isn't worth the benefit here. But if you want to add tests and docs and complete the work for the patch, go ahead and it will be evaluated on its merits. You can reopen the ticket then.

10/12/07 16:14:49 changed by david

I concur with Rick and Josh, but I do applaud you for taking the time to attempt to improve Rails. Just because this patch might not be deemed worth it in the end, it's still a good first step on your path to becoming a successful Rails contributor. So kudos to you for giving it a shot.

10/14/07 03:07:04 changed by bitsweat

  • milestone changed from 2.0 to 2.x.

10/15/07 01:28:02 changed by albus522

  • status changed from closed to reopened.
  • resolution deleted.

All right here I go for round 2.

The reason delegate will not work for my situation is that I need to extend the association. I also have a permissions system setup and I want to be able to do @app.users.with_access which would give me the users with access to the specific application.

Next you were right I did break eager loading and <<. I found in testing this that eager loading was already broken for a has_many :through that used a source that was an sti association using a non standard foreign_key. I can separate out a patch for that specific issue for quicker application if desired. I managed to get both eager loading and << working.

In running the tests I found out that all.sh is not running any of the tests in the associations folder. I am not sure if this was intentional but I have also included a fix for that in my patch. That I can also separate out into a another patch.

Lastly I updated all the related documentation that I could find.

10/15/07 01:29:36 changed by albus522

  • attachment active_record_7892.diff added.

Diff against trunk/activerecord revision 7892

10/15/07 06:35:26 changed by tarmo

There seems to be an inconsistency in the documentation:

+    #   class App < ActiveRecord::Base
+    #     belongs_to :client
+    #   @app = App.find :first
+    #   @app.clients.collect { |c| c.users }.flatten # select all the users for a given application

"@app.clients" does not make sense when App belongs_to :client.

10/15/07 13:16:32 changed by albus522

You are correct. I have corrected the documentation and updated the patch to be against revision 7917.

10/15/07 13:17:32 changed by albus522

  • attachment active_record_7917.diff added.

Diff against trunk/activerecord revision 7917

11/13/07 18:59:07 changed by ewildgoose

What is the status on this enhancement?

I just ran into the same issue and using the delegate method has definite limitations, in particular where you have built an app around the whole associations idea. For example ActiveScaffold needs a whole bunch of workaround code because the delegate isn't a proper association that it can scan and figure out. As albus522 pointed out it also removes the ability to extend the association and add methods around it (eg security)

What are the blocking issues preventing this from being committed?

12/22/07 19:53:41 changed by pablomartinez

I've tried the patch and it seems to work. It solves the issue described in this ticket, is there any to reason to hold back the patch?