Note that there are some explanatory texts on larger screens.

plurals
  1. POAdd record to a model upon create used in many models
    primarykey
    data
    text
    <p>I have a survey and I would like to add participants to a <code>Participant</code> model whenever a user answers to a question for the first time. The survey is a bit special because it has many functions to answer questions such as Tag words, Multiple choices and Open Question and each function is actually a model that has its own records. Also I only want the Participant to be saved once.</p> <p>The Participant model is fairly simple:</p> <pre><code>class Participant &lt; ActiveRecord::Base belongs_to :survey attr_accessible :survey_id, :user_id end </code></pre> <p>The Survey model is also straightforward:</p> <pre><code>class Survey &lt; ActiveRecord::Base ... has_many :participants, :through =&gt; :users has_many :rating_questions, :dependent =&gt; :destroy has_many :open_questions, :dependent =&gt; :destroy has_many :tag_questions, :dependent =&gt; :destroy belongs_to :account belongs_to :user accepts_nested_attributes_for :open_questions accepts_nested_attributes_for :rating_questions accepts_nested_attributes_for :tag_questions ... end </code></pre> <p>Then you have models such as <code>rating_answers</code> that belong to a <code>rating_question</code>, <code>open_answers</code> that belong to <code>open_questions</code> and so on. </p> <p>So initially I thought for within my model <code>rating_answers</code> I could add <code>after_create</code> callback to add_participant</p> <p>like this:</p> <pre><code>class RatingAnswer &lt; ActiveRecord::Base belongs_to :rating_question after_create :add_participant ... protected def add_participant @participant = Participant.where(:user_id =&gt; current_user.id, :survey_id =&gt; Survey.find(params[:survey_id])) if @participant.nil? Participant.create!(:user_id =&gt; current_user.id, :survey_id =&gt; Survey.find(params[:survey_id])) end end end </code></pre> <p>In this case, I didn't know how to find the survey_id, so I tried using the params but I don't think that is the right way to do it. regardles it returned this error</p> <pre><code>NameError (undefined local variable or method `current_user' for #&lt;RatingAnswer:0x0000010325ef00&gt;): app/models/rating_answer.rb:25:in `add_participant' app/controllers/rating_answers_controller.rb:12:in `create' </code></pre> <p>Another idea I had was to create instead a module <code>Participants.rb</code> that I could use in each controllers</p> <pre><code>module Participants def add_participant @participant = Participant.where(:user_id =&gt; current_user.id, :survey_id =&gt; Survey.find(params[:survey_id])) if @participant.nil? Participant.create!(:user_id =&gt; current_user.id, :survey_id =&gt; Survey.find(params[:survey_id])) end end end </code></pre> <p>and in the controller</p> <pre><code>class RatingAnswersController &lt; ApplicationController include Participants def create @rating_question = RatingQuestion.find_by_id(params[:rating_question_id]) @rating_answer = RatingAnswer.new(params[:rating_answer]) @survey = Survey.find(params[:survey_id]) if @rating_answer.save add_participant respond_to do |format| format.js end end end end </code></pre> <p>And I got a routing error</p> <pre><code>ActionController::RoutingError (uninitialized constant RatingAnswersController::Participants): </code></pre> <p>I can understand this error, because I don't have a controller for participants with a create method and its routes resources</p> <p>I am not sure what is the proper way to add a record to a model from a nested model and what is the cleaner approach. </p> <p>Ideas are most welcome!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload