# Help With has\_many and belongs\_to :through assocaitions

**URL:** <https://www.ruby-forum.com/t/help-with-has-many-and-belongs-to-through-assocaitions/73337>\
**Category:** Rails\
**Created:** [October 23, 2006, 10:17pm UTC](https://www.ruby-forum.com/t/help-with-has-many-and-belongs-to-through-assocaitions/73337 "2006-10-23T22:17:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [October 23, 2006, 10:17pm UTC](https://www.ruby-forum.com/t/help-with-has-many-and-belongs-to-through-assocaitions/73337/1 "2006-10-23T22:17:52Z")

</div>

Hi all, I am having problems with some reasonably complex assocaitions  
involving has\_many and belongs\_to with the :through option.

I have three models:

class Site \< ActiveRecord::Base  
has\_many :site\_page\_relationships  
has\_many :pages, :through =\>  
:pagesite\_page\_relationships\_relationships, :source =\> :child\_page  
end

class PageRelationship \< ActiveRecord::Base  
belongs\_to :site  
belongs\_to :parent\_page, :foreign\_key =\> :parent\_page\_id,  
:class\_name =\> :page  
belongs\_to :child\_page, :foreign\_key =\> :child\_page\_id,  
:class\_name =\> :page  
end

class Page \< ActiveRecord::Base  
has\_many :page\_relationships, :foreign\_key =\> :child\_page\_id  
has\_many :child\_pages, :through =\> :page\_relationships,  
:source =\> :child\_page  
has\_many :parent\_pages, :through =\> :page\_relationships,  
:source =\> :parent\_page  
end

The idea being that you can have multipe sites each with their own  
sitetree, and the ability to share pages between sites but in different  
positions in the site tree.

When I try the following in ‘script/console’:

> > page1 = Page.new  
> > =\> #\<Page:0x279bb60 @attributes={}, @new\_record=true\>
> 
> > page1.save  
> > =\> true
> 
> > page2 = Page.new  
> > =\> #\<Page:0x27944b4 @attributes={}, @new\_record=true\>
> 
> > page2.save  
> > =\> true
> 
> > site = Site.new  
> > =\> #\<Site:0x278e208 @attributes={“name”=\>nil, “updated\_at”=\>nil,  
> > “url”=\>nil, “description”=\>nil, “created\_at”=\>nil}, @new\_record=true\>
> 
> > site.save  
> > =\> true
> 
> > rel1 = PageRelationship.new(:parent\_page =\> page1, :child\_page =\> page2, :site =\> site)  
> > TypeError: can’t convert Symbol into String  
> > from  
> > /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active\_record/base.rb:1003:in  
> > `type_name_with_module' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:1242:in`compute\_type’  
> > from  
> > /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active\_record/reflection.rb:112:in  
> > `klass' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations/association_proxy.rb:133:in`raise\_on\_type\_mismatch’  
> > from  
> > /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active\_record/associations/belongs\_to\_association.rb:22:in  
> > `replace' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:850:in`child\_page=’  
> > from  
> > /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active\_record/base.rb:1510:in  
> > `attributes=' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:1509:in`attributes=’  
> > from  
> > /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active\_record/base.rb:1354:in  
> > `initialize_without_callbacks' from /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/callbacks.rb:236:in`initialize’  
> > from (irb):11  
> > from :0

You can see that I get this error? It’s really bugging me, I can’t  
figure out why. Any suggestions/ideas would be much appreciated.

Many Thanks

Mark D.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [October 23, 2006, 10:34pm UTC](https://www.ruby-forum.com/t/help-with-has-many-and-belongs-to-through-assocaitions/73337/2 "2006-10-23T22:34:08Z")

</div>

> ```
> :class_name => :page
> 
> ```
> 
> end
> 
> The idea being that you can have multipe sites each with their own  
> sitetree, and the ability to share pages between sites but in different  
> positions in the site tree.

If I understood your domain, it is like :

Site 1 -----\> SiteTree 1  
Site 2 ------\> SiteTree 2  
and so on.

Then SiteTree has many Pages. So it looks like you have one-to-one  
relationship between Site and SiteTree. SiteTree and Pages many to many  
relationship.

If that is the case then your model should break the many-to-many  
relationship between SiteTree and Page classes.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [October 23, 2006, 10:41pm UTC](https://www.ruby-forum.com/t/help-with-has-many-and-belongs-to-through-assocaitions/73337/3 "2006-10-23T22:41:44Z")

</div>

removed\_email\_address@domain.invalid wrote:

> Hi all, I am having problems with some reasonably complex assocaitions  
> involving has\_many and belongs\_to with the :through option.
> 
> I have three models:
> 
> class Site \< ActiveRecord::Base  
> has\_many :site\_page\_relationships  
> has\_many :pages, :through =\>  
> :pagesite\_page\_relationships\_relationships, :source =\> :child\_page  
> end
> 
> class PageRelationship \< ActiveRecord::Base  
> belongs\_to :site  
> belongs\_to :parent\_page, :foreign\_key =\> :parent\_page\_id,  
> :class\_name =\> :page  
> belongs\_to :child\_page, :foreign\_key =\> :child\_page\_id,  
> :class\_name =\> :page  
> end
> 
> class Page \< ActiveRecord::Base  
> has\_many :page\_relationships, :foreign\_key =\> :child\_page\_id  
> has\_many :child\_pages, :through =\> :page\_relationships,  
> :source =\> :child\_page  
> has\_many :parent\_pages, :through =\> :page\_relationships,  
> :source =\> :parent\_page  
> end
> 
> The idea being that you can have multipe sites each with their own  
> sitetree, and the ability to share pages between sites but in different  
> positions in the site tree.
> 
> When I try the following in ‘script/console’:
> 
> > > page1 = Page.new  
> > > =\> #\<Page:0x279bb60 @attributes={}, @new\_record=true\>  
> > > page1.save  
> > > =\> true  
> > > page2 = Page.new  
> > > =\> #\<Page:0x27944b4 @attributes={}, @new\_record=true\>  
> > > page2.save  
> > > =\> true  
> > > site = Site.new  
> > > =\> #\<Site:0x278e208 @attributes={“name”=\>nil, “updated\_at”=\>nil,  
> > > “url”=\>nil, “description”=\>nil, “created\_at”=\>nil}, @new\_record=true\>  
> > > site.save  
> > > =\> true  
> > > rel1 = PageRelationship.new(:parent\_page =\> page1, :child\_page =\> page2, :site =\> site)  
> > > TypeError: can’t convert Symbol into String  
> > > from  
> > > /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active\_record/base.rb:1003:in  
> > > `type\_name\_with\_module’

Your Page model doesn’t have the right associations for a  
self-referential hmt relationship. You need two different has\_many  
assocs for the parent and child refs to the join model. This is like  
having different aliases for your joins in SQL. Take a look at my  
posting on this:

[http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through](http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through)

Also, your Site class has some weird named assocs. That might be the  
source of your error. Remember, if the model name can’t be inferred from  
the assoc name, you need to specify it with options.

–  
Josh S.  
[http://blog.hasmanythrough.com](http://blog.hasmanythrough.com)

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [October 23, 2006, 11:40pm UTC](https://www.ruby-forum.com/t/help-with-has-many-and-belongs-to-through-assocaitions/73337/4 "2006-10-23T23:40:54Z")

</div>

Bala P. wrote:

> > Also, your Site class has some weird named assocs. That might be the  
> > source of your error. Remember, if the model name can’t be inferred from  
> > the assoc name, you need to specify it with options.
> 
> Edge (n) \<-------------------\>(1) Node -----  
> ^\_\_\_\_\_|
> 
> Is the diagram correct? Node has the self-reference and you have one to  
> many  
> relationship between the Node and the Edges.

Yes.

–  
Josh S.  
[http://blog.hasmanythrough.com](http://blog.hasmanythrough.com)

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [October 23, 2006, 11:04pm UTC](https://www.ruby-forum.com/t/help-with-has-many-and-belongs-to-through-assocaitions/73337/5 "2006-10-23T23:04:52Z")

</div>

> Also, your Site class has some weird named assocs. That might be the  
> source of your error. Remember, if the model name can’t be inferred from  
> the assoc name, you need to specify it with options.

Edge (n) \<-------------------\>(1) Node -----  
^\_\_\_\_\_|

Is the diagram correct? Node has the self-reference and you have one to  
many  
relationship between the Node and the Edges.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [October 24, 2006, 1:35am UTC](https://www.ruby-forum.com/t/help-with-has-many-and-belongs-to-through-assocaitions/73337/6 "2006-10-24T01:35:40Z")

</div>

Many thanks for all your help, I have now managed to fix it. After  
reading John’s post ’ Self-referential has\_many :through associations’  
I sorted it.

Great to get such a quick response from people. First time I posted a  
question here! Was very happy indeed. My new models which work are as  
follows:

class Site \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :users  
has\_many :page\_relationships  
has\_many :pages, :through =\> :page\_relationships, :source =\>  
:child\_page  
end

class PageRelationship \< ActiveRecord::Base  
belongs\_to :site  
belongs\_to :parent\_page, :foreign\_key =\> ‘parent\_page\_id’,  
:class\_name =\> ‘Page’  
belongs\_to :child\_page, :foreign\_key =\> ‘child\_page\_id’,  
:class\_name =\> ‘Page’  
end

class Page \< ActiveRecord::Base  
has\_many :page\_relationships\_as\_child, :foreign\_key =\>  
‘child\_page\_id’,  
:class\_name =\> ‘PageRelationship’  
has\_many :page\_relationships\_as\_parent, :foreign\_key =\>  
‘parent\_page\_id’,  
:class\_name =\> ‘PageRelationship’  
has\_many :child\_pages, :through =\> :page\_relationships\_as\_child  
has\_many :parent\_pages, :through =\> :page\_relationships\_as\_parent  
end

Cheers again, Mark
