# Multiple polymorphic belongs\_to declarations

**URL:** <https://www.ruby-forum.com/t/multiple-polymorphic-belongs-to-declarations/55331>\
**Category:** Rails\
**Created:** [March 19, 2006, 9:52pm UTC](https://www.ruby-forum.com/t/multiple-polymorphic-belongs-to-declarations/55331 "2006-03-19T21:52:18Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![janke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/d26b3c/32.png) [@janke](https://www.ruby-forum.com/u/janke)\
**Post date:** [March 19, 2006, 9:52pm UTC](https://www.ruby-forum.com/t/multiple-polymorphic-belongs-to-declarations/55331/1 "2006-03-19T21:52:18Z")

</div>

I have the following models:

```
class Card < ActiveRecord::Base
  belongs_to :deck
  belongs_to :front, :polymorphic => true
  belongs_to :back, :polymorphic => true
end

class TextContent < ActiveRecord::Base
  has_one :card, :as => :front
  has_one :card, :as => :back
end

```

The conflicting has\_one declarations don’t work. What I need is a way to  
name the belongs\_to associations ‘front’ and ‘back’, but have them go  
through a single interface, which the TextContent model can reference,  
like:

```
class Card < ActiveRecord::Base
  belongs_to :deck
  belongs_to :front, :polymorphic => true, :interface => :content
  belongs_to :back, :polymorphic => true, :interface => :content
end

class TextContent < ActiveRecord::Base
  has_one :card, :as => :content
end

```

Is this possible? Or is there some other way I should relate these  
models?

---

<div class="post-metadata">

**Author:** ![janke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/d26b3c/32.png) [@janke](https://www.ruby-forum.com/u/janke)\
**Post date:** [March 19, 2006, 10:36pm UTC](https://www.ruby-forum.com/t/multiple-polymorphic-belongs-to-declarations/55331/2 "2006-03-19T22:36:08Z")

</div>

On Sunday, March 19, 2006, at 9:52 PM, Thomas Jack wrote:

> ```
> has_one :card, :as => :back
> belongs_to :back, :polymorphic => true, :interface => :content
> 
> ```
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> * * *
> 
> Rails mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)

Could you supply the following to help with the discussion:  
a) your schema for these tables,  
b) what do you mean by “doesn’t work”? are you getting an error, or the  
behavior isn’t what you expect, etc.

adam

---

<div class="post-metadata">

**Author:** ![janke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/d26b3c/32.png) [@janke](https://www.ruby-forum.com/u/janke)\
**Post date:** [March 20, 2006, 4:33am UTC](https://www.ruby-forum.com/t/multiple-polymorphic-belongs-to-declarations/55331/3 "2006-03-20T04:33:16Z")

</div>

adam ingramgoble wrote:

> Could you supply the following to help with the discussion:  
> a) your schema for these tables,

```
create_table :cards do |t|
  t.column :deck_id, :integer, :null => false
  t.column :front_id, :integer, :null => false
  t.column :front_type, :string, :null => false
  t.column :back_id, :integer, :null => false
  t.column :back_type, :string, :null => false
end

create_table :decks do |t|
  t.column :title, :string, :null => false
  t.column :created_at, :datetime, :null => false
end

create_table :text_contents do |t|
  t.column :content, :text, :null => false
end

```

> b) what do you mean by “doesn’t work”? are you getting an error, or the  
> behavior isn’t what you expect, etc.

The polymorphic belongs\_to declarations work fine. I can do things like  
@card.front = TextContent.new(:content =\> “some text”) and the  
front\_type and front\_id work properly.

However, the two has\_one declarations conflict. They both expose a card  
attribute, so the second has\_one just overrides the first. Consider the  
following console session, for example:

```
Loading development environment.
>> front = TextContent.new(:content => 'front of card')
=> #<TextContent:0x382a800 @new_record=true, 

```

@attributes={“content”=\>“front of card”}\>  
\>\> back = TextContent.new(:content =\> ‘back of card’)  
=\> #\<TextContent:0x381e908 @new\_record=true,  
@attributes={“content”=\>“back of card”}\>  
\>\> card = Card.new(:front =\> front, :back =\> back)  
=\> #\<Card:0x3817870 @new\_record=true, @front=#\<TextContent:0x382a800  
@new\_record=true, @attributes={“content”=\>“front of card”}\>,  
#attributes={“front\_id”=\>0, “deck\_id”=\>0, “back\_type”=\>"", “back\_id”=\>0,  
“front\_type”=\>""}, @back=#\<TextContent:0x381e908 @new\_record=true,  
@attributes={“content”=\>“back of card”}\>\>  
\>\> card.save  
=\> true  
\>\> card.front  
=\> #\<TextContent:0x382a800 @new\_record=true,  
@attributes={“content”=\>“front of card”}\>  
\>\> card.back  
=\> #\<TextContent:0x381e908 @new\_record=true,  
@attributes={“content”=\>“back of card”}\>  
\>\> card.front.card  
=\> nil  
\>\> card.back.card  
=\> #\<Card:0x37e5698 @attributes={“id”=\>“2”, “front\_id”=\>“3”,  
“deck\_id”=\>“0”, “back\_type”=\>“TextContent”, “back\_id”=\>“4”,  
“front\_type”=\>“TextContent”}\>

Note that the .front and .back attributes of the Card model work fine,  
but that only the second has\_one works for the TextContent model.
