Forum: Ruby on Rails has_many :through => has_many

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Bde8d8f24c1ca83f452b5a9d03d5ead6?d=identicon&s=25 Wouter de Bie (xinit)
on 2009-01-30 14:47
Hi all!

I'm trying to do the following thing:

class Show < ActiveRecord::Base
  has_many :pools
  has_many :tickets, :through => :pools
end

class Pool < ActiveRecord::Base
  belongs_to :show
  has_many :tickets
end

class Ticket < ActiveRecord::Base
  belongs_to :pool
end

Now with an instance of Show, the following works correctly:
show.tickets

But when I create a new show, Rails wants to build tickets or do
something with it. An
ActiveRecord::HasManyThroughCantAssociateThroughHasManyReflection is
raised with the message "Cannot modify association 'Show#tickets'
because the source reflection class 'Ticket' is associated to 'Pool' via
:has_many."

I don't quite understand this, since the API docs tell me that:

: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.

At the top of the backtrace I see that Rails is trying to insert a
record for the association. Why?

Is there a way to work around this?

Thanks!

Wouter
Bde8d8f24c1ca83f452b5a9d03d5ead6?d=identicon&s=25 Wouter de Bie (xinit)
on 2009-01-30 15:17
Forgot to mention that I have an after_save that uses Pool. Here it goes
wrong..

Now I have to figure out a way to do the after save correctly.
Bde8d8f24c1ca83f452b5a9d03d5ead6?d=identicon&s=25 Wouter de Bie (xinit)
on 2009-01-30 15:43
Problem solved:

I had the after_save before the association declaration. Defining them
after the associations solved it.
8b38b02fa2142aeacd81114926f94789?d=identicon&s=25 Fritz Rodriguez (frgooall)
on 2012-01-14 05:12
Hello All

This is my first time on ruby-forum so pardon if this is not posted
correctly.

I am having a very similar issue regarding has_many through has_many.  A
logged user can create a work order and associated fields in models name
alias and sub_tasks.  I am using active_admin and an admin user can view
and edit the above mentioned models, but when admin tries to create a
sub_task I can get the following error:

Cannot modify association 'WorkOrder#sub_tasks' because the source
reflection class 'SubTask' is associated to 'NameAlias' via :has_many.

the models:

 class work_order < ActiveRecord::Base
  has_many :name_aliases
  has_many :sub_tasks, :through => :name_aliases
end

class NameAlias < ActiveRecord::Base
  belongs_to :work_order
  has_many :sub_tasks
end

class SubTask < ActiveRecord::Base
  belongs_to :name_alias
  belongs_to :work_order
end

A pervious post mentioned a solution using an after_save method  before
declaring the association... but I didn't see sample code? since i am
new to rails it would be helpful to see or example how this can be
resolved.  Thanks for your help!

Best,
Fritz
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2012-01-14 10:36
(Received via mailing list)
On 14 January 2012 04:12, Fritz Rodriguez <lists@ruby-forum.com> wrote:
>
> class NameAlias < ActiveRecord::Base
> belongs_to :work_order
> has_many :sub_tasks
> end
>
> class SubTask < ActiveRecord::Base
> belongs_to :name_alias
> belongs_to :work_order

This should be belongs_to :through name_alias.  It must mirror the
has_many sub_tasks :through in work_order

You should really have started a new thread for this as it is nothing
to do with the original post.

Colin
8b38b02fa2142aeacd81114926f94789?d=identicon&s=25 Fritz Rodriguez (frgooall)
on 2012-01-14 17:59
Attachment: has_many_through.txt (2 KB)
Colin Law wrote in post #1040834:
> On 14 January 2012 04:12, Fritz Rodriguez <lists@ruby-forum.com> wrote:
>>
>> class NameAlias < ActiveRecord::Base
>> belongs_to :work_order
>> has_many :sub_tasks
>> end
>>
>> class SubTask < ActiveRecord::Base
>> belongs_to :name_alias
>> belongs_to :work_order
>
> This should be belongs_to :through name_alias.  It must mirror the
> has_many sub_tasks :through in work_order
>
> You should really have started a new thread for this as it is nothing
> to do with the original post.
>
> Colin

Colin, Thanks for your reply and my apologies regarding proper placement
of the is post.

I believe you said the SubTask model should mirror through in
work_order?

class SubTask < ActiveRecord::Base
  attr_accessible :name_alias_id, :work_order_id, :status, :title

  belongs_to :name_alias
  belongs_to :work_order, :through => :name_alias

  accepts_nested_attributes_for :name_alias
  accepts_nested_attributes_for :work_order

This produced a "Unknown key: through" error? Not sure I place the
association in the correct model, I have attached a file for reference.
I appreciate your help!
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2012-01-14 18:13
(Received via mailing list)
On 14 January 2012 16:59, Fritz Rodriguez <lists@ruby-forum.com> wrote:
>>> belongs_to :work_order
> of the is post.
> accepts_nested_attributes_for :name_alias
> accepts_nested_attributes_for :work_order
>
> This produced a "Unknown key: through" error? Not sure I place the
> association in the correct model, I have attached a file for reference.

Sorry, I was talking drivel.  belongs_to :through is not supported.
You should just have belongs_to :name_alias.

Colin
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2012-01-14 18:21
(Received via mailing list)
On 14 January 2012 16:59, Fritz Rodriguez <lists@ruby-forum.com> wrote:
>>> belongs_to :work_order
> of the is post.
> accepts_nested_attributes_for :name_alias
> accepts_nested_attributes_for :work_order
>
> This produced a "Unknown key: through" error? Not sure I place the
> association in the correct model, I have attached a file for reference.
> I appreciate your help!
>
> Attachments:
> http://www.ruby-forum.com/attachment/6910/has_many...

By the way, in the attachment you have multiple default scopes for
WorkOrder.  I think only one is allowed.  You can order by multiple
fields in one scope of course if that is what you want.  Be careful
with specifying the order in default scope though, it is not possible
to override this (or at least it did not used to be possible) as the
default scope order is applied *after* any others.

Colin
8b38b02fa2142aeacd81114926f94789?d=identicon&s=25 Fritz Rodriguez (frgooall)
on 2012-01-14 18:51
Colin Law wrote in post #1040893:
> On 14 January 2012 16:59, Fritz Rodriguez <lists@ruby-forum.com> wrote:
>>>> belongs_to :work_order
>> of the is post.
>> accepts_nested_attributes_for :name_alias
>> accepts_nested_attributes_for :work_order
>>
>> This produced a "Unknown key: through" error? Not sure I place the
>> association in the correct model, I have attached a file for reference.
>> I appreciate your help!
>>
>> Attachments:
>> http://www.ruby-forum.com/attachment/6910/has_many...
>
> By the way, in the attachment you have multiple default scopes for
> WorkOrder.  I think only one is allowed.  You can order by multiple
> fields in one scope of course if that is what you want.  Be careful
> with specifying the order in default scope though, it is not possible
> to override this (or at least it did not used to be possible) as the
> default scope order is applied *after* any others.
>
> Colin

Thanks, make sense regarding default scope... still getting the error?
wired, that a logged user can create and edit a sub_task, but admin user
via acitve_admin can edit but not create a sub_task?

Do you/available for consulting/help with a projects? if so, how does it
work? per hour, etc..

Thanks and have a great day

Best,
Fritz
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2012-01-14 22:42
(Received via mailing list)
On 14 January 2012 17:51, Fritz Rodriguez <lists@ruby-forum.com> wrote:
>>>
>> Colin
>
> Thanks, make sense regarding default scope... still getting the error?

Is that a question?  Did you add the id column to the table and run
the migration?
Show us the complete error message and stack trace and the section of
your code that is causing it.

> wired, that a logged user can create and edit sub_task, but admin user
> via acitve_admin can edit but no create a sub_task?

It is executing different code or with different data and causing the
error.  Nothing weird about it.

>
> Do you/available for consulting/help with a projects? if so, how does it
> work? per hour, etc..

No, I just try to help out in my spare time.

Colin
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2012-01-14 22:59
(Received via mailing list)
On 14 January 2012 21:41, Colin Law <clanlaw@googlemail.com> wrote:
>>>> I appreciate your help!
>>>
>>> Colin
>>
>> Thanks, make sense regarding default scope... still getting the error?
>
> Is that a question? Did you add the id column to the table and run
> the migration?

What am I talking about?  That was someone else in a different thread.
 Ignore the id comment.

Colin

>> Do you/available for consulting/help with a projects? if so, how does it
>> work? per hour, etc..
>
> No, I just try to help out in my spare time.
>
> Colin



--
gplus.to/clanlaw
8b38b02fa2142aeacd81114926f94789?d=identicon&s=25 Fritz Rodriguez (frgooall)
on 2012-01-14 23:21
Attachment: full_trace.txt (10 KB)
Okay, thanks!  Here is the full trace with code section, appreciate any
insight!
8b38b02fa2142aeacd81114926f94789?d=identicon&s=25 Fritz Rodriguez (frgooall)
on 2012-01-15 04:50
Thanks for your help Colin, resolved the issued by changing my model
associations....

class NameAlias < ActiveRecord::Base
  has_many :sub_tasks
  has_many :work_orders, :through => :sub_tasks

class SubTask < ActiveRecord::Base
  belongs_to :name_alias
  belongs_to :work_order

class WorkOrder < ActiveRecord::Base
  has_many :sub_tasks
  has_many :name_aliases, :through => :sub_tasks
This topic is locked and can not be replied to.