Создание объекта по рельсам полиморфной ассоциации

Мне нужно (или я думаю) реализовать полиморфную ассоциацию в моей модели, но у меня что-то не так. Давайте посмотрим на мою ситуацию, это простая система вопросов / ответов, и логика следующая: - на вопрос можно ответить с помощью N ответов. - Ответом может быть только "текстовое" XOR (одно или другое, но не оба) "картинка".

Миграции:

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

Модели * 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

Контроллер 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
...

И просмотреть форму (только эти поля):

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

Итак, проблема в том, что когда я отправляю форму, я получаю эту ошибку:

неопределенный метод new' for nil:NilClass app/controllers/answers_controller.rb:52:increate '

Ответы? :)


person Martin B.    schedule 12.11.2012    source источник
comment
Хм, не уверен, актуально ли это, но я бы использовал attr_accessible :answerable_type, :answerable_id   -  person MrYoshiji    schedule 13.11.2012
comment
что возвращает @ answerable.answer.class после create_answerable в методе create?   -  person awenkhh    schedule 13.11.2012
comment
@awenkhh create_answerable создает экземпляр унаследованного класса (AnswerText или AnswerPicture) в соответствии с типом параметра (текст или изображение).   -  person Martin B.    schedule 13.11.2012
comment
Попробуйте изменить create_answerable(post[:answerable_type], post[:answerable]) на @answerable = create_answerable(post[:answerable_type], post[:answerable])   -  person Thanh    schedule 13.11.2012


Ответы (1)


в отношениях has_one вы должны использовать:

@answerable.build_answer

or

@answerable.create_answer

вместо того

@answerable.answer.new

см. ссылку для получения дополнительной информации.

person m_x    schedule 13.11.2012
comment
Спасибо, вы правы. Мне пришлось использовать @ answerable.create_answer. - person Martin B.; 14.11.2012
comment
и попробуйте (@ answerable.answer || @ answerable.create_answer), если ответ может уже существовать - person schory; 07.08.2013