Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating object by Polymorphic association rails

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:increate'

Answers? :)

like image 590
Martin B. Avatar asked Nov 12 '12 20:11

Martin B.


People also ask

How is polymorphic association set up in Rails?

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.

What is polymorphic association in Rails?

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.

How does polymorphism work in Ruby?

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.

How many types of associations are there in Rails?

Rails supports six types of associations: belongs_to.


1 Answers

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.

like image 154
m_x Avatar answered Nov 04 '22 12:11

m_x