I need (or I think) implement polymorphic association in my model but I have something wrong. Let see my situation, it's a simple question/answers system, and the logic is the following: - a question can be ansewered by N answers. - An answer can be only a "text" XOR (one or other, not both) a "picture".
Migrations:
class CreateAnswers < ActiveRecord::Migration
def change
create_table :answers do |t|
t.integer :question_id
t.references :answerable, :polymorphic => true
t.timestamps
end
end
end
class CreateAnswerTexts < ActiveRecord::Migration
def change
create_table :answer_texts do |t|
t.text :content
t.timestamps
end
end
end
class CreateAnswerPictures < ActiveRecord::Migration
def change
create_table :answer_pictures do |t|
t.string :content
t.timestamps
end
end
end
Models *answer.rb*
class Answer < ActiveRecord::Base
belongs_to :user_id
belongs_to :question_id
belongs_to :answerable, :polymorphic => true
attr_accessible :answerable_type
end
answer_text.rb
class AnswerText < ActiveRecord::Base
TYPE = "text"
has_one :answer, :as => :answerable
attr_accessible :content
end
answer_picture.rb
class AnswerPicture < ActiveRecord::Base
TYPE = "picture"
has_one :answer, :as => :answerable
attr_accessible :content
end
Controller answers_controller.rb:
...
def create
post = params[:answer]
create_answerable(post[:answerable_type], post[:answerable])
@answer = @answerable.answer.new()
end
private
def create_answerable(type, content)
@answerable = ('Answer' + type.capitalize).classify.constantize.new(:content => content)
@answerable.save
end
...
And view form (Only have these fields):
...
<div class="field">
<%= f.label :answerable_type %><br />
<%= select("answer", "answerable_type", Answer::Types, {:include_blank => true}) %>
</div>
<div class="field">
<%= f.label :answerable %><br />
<%= f.text_field :answerable %>
</div>
...
So, the problem is when I submit form I get this error:
undefined method
new' for nil:NilClass app/controllers/answers_controller.rb:52:in
create'
Answers? :)
The basic structure of a polymorphic association (PA)sets up 2 columns in the comment table. (This is different from a typical one-to-many association, where we'd only need one column that references the id's of the model it belongs to). For a PA, the first column we need to create is for the selected model.
Polymorphic relationship in Rails refers to a type of Active Record association. This concept is used to attach a model to another model that can be of a different type by only having to define one association.
Polymorphism works well in Ruby on Rails as an Active Record association. If models essentially do the same thing, we can turn them into one single model to create a polymorphic relationship. In this example, we have an ERD for an application where a user can post an instrument with its details.
Rails supports six types of associations: belongs_to.
on a has_one
relationship, you have to use :
@answerable.build_answer
or
@answerable.create_answer
instead of
@answerable.answer.new
see the reference for more info.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With