2012-11-12 9 views
8

Ich brauche (oder ich denke) implementieren polymorphe Assoziation in meinem Modell, aber ich habe etwas falsch. Lassen Sie meine Situation sehen, es ist ein einfaches Frage/Antwort-System, und die Logik ist folgende: - eine Frage kann durch N Antworten beantwortet werden. - Eine Antwort kann nur ein "Text" XOR (ein oder anderes, nicht beides) ein "Bild" sein.Erstellen von Objekt durch polymorphe Association Schienen

Migrationen:

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 

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

Und Ansicht Form (Nur diese Felder haben):

... 
<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 ist das Problem, wenn ich Formular ich diesen Fehler:

undefined method new' for nil:NilClass app/controllers/answers_controller.rb:52:in create'

Antworten? :)

+0

Hmm nicht sicher, ob es relevant ist, aber ich würde verwenden 'attr_accessible: ansarbeable_type,: ansprechende_id' – MrYoshiji

+0

Was gibt @ answerable.answer.class nach create_ansherable in der create-Methode zurück? – awenkhh

+0

@awenkhh create_answerable erstellt eine Instanz der geerbten Klasse (AnswerText oder AnswerPicture) entsprechend dem Param-Typ ("text" oder "picture"). –

Antwort

18

auf einer has_one Beziehung, müssen Sie verwenden:

@answerable.build_answer 

oder

@answerable.create_answer 

statt

@answerable.answer.new 

siehe the reference für weitere Informationen.

+0

Danke, Sie haben Recht. Ich musste @ answerable.create_answer verwenden. –

+0

und versuchen Sie (@ answerable.answer || @ answerable.create_answer), ob die Antwort bereits existiert – schory

Verwandte Themen