2013-11-27 2 views
0

У меня есть опрос, и я хотел бы добавить участников в модель Participant всякий раз, когда пользователь впервые отвечает на вопрос. Опрос немного особенный, поскольку он имеет множество функций для ответа на такие вопросы, как слова тегов, множественные варианты и открытый вопрос, и каждая функция на самом деле является моделью, которая имеет свои собственные записи. Также я хочу, чтобы Участник был сохранен один раз.Добавить запись в модель после создания, используемой во многих моделях

Участник модель довольно прост:

class Participant < ActiveRecord::Base 
    belongs_to :survey 
    attr_accessible :survey_id, :user_id 
end 

Модель обследования также прост:

class Survey < ActiveRecord::Base 
    ... 
    has_many :participants, :through => :users 
    has_many :rating_questions, :dependent => :destroy 
    has_many :open_questions, :dependent => :destroy 
    has_many :tag_questions, :dependent => :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 

Тогда у вас есть такие модели, как rating_answers, которые принадлежат к rating_question, open_answers, которые принадлежат open_questions и так далее.

Так первоначально я думал в моей модели rating_answers я мог бы добавить after_create обратного вызова add_participant

так:

class RatingAnswer < ActiveRecord::Base 
    belongs_to :rating_question 
    after_create :add_participant 
    ... 
    protected 
    def add_participant 
    @participant = Participant.where(:user_id => current_user.id, :survey_id => Survey.find(params[:survey_id])) 
    if @participant.nil? 
     Participant.create!(:user_id => current_user.id, :survey_id => Survey.find(params[:survey_id])) 
    end 
    end 
end 

В этом случае, я не знаю, как найти survey_id, так Я попытался использовать параметры, но я не думаю, что это правильный способ сделать это. regardles вернулся эту ошибку

NameError (undefined local variable or method `current_user' for #<RatingAnswer:0x0000010325ef00>): 
    app/models/rating_answer.rb:25:in `add_participant' 
    app/controllers/rating_answers_controller.rb:12:in `create' 

Еще одна идея у меня была в том, чтобы создать вместо модуля Participants.rb, что я мог бы использовать в каждом из контроллеров

module Participants 
    def add_participant 
    @participant = Participant.where(:user_id => current_user.id, :survey_id => Survey.find(params[:survey_id])) 
    if @participant.nil? 
     Participant.create!(:user_id => current_user.id, :survey_id => Survey.find(params[:survey_id])) 
    end 
    end 
end 

и в контроллере

class RatingAnswersController < 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 

И I получена ошибка маршрутизации

ActionController::RoutingError (uninitialized constant RatingAnswersController::Participants): 

Я могу понять эту ошибку, потому что у меня нет контроллера для участников с методом создания и его маршрутами ресурсов

Я не уверен, что это правильный способ, чтобы добавить запись к модели от вложенного модель и что является более чистым подходом.

Идеи приветствуются!

+1

current_user - это помощник, доступный только в режимах view/controller. Вам нужно передать его в качестве параметра в модель. Кроме того, он недоступен в моделях. –

+0

Я также вижу, что вы не передаете никакие данные рейтинга-запроса при создании объекта рейтинга-ответа. –

+0

Спасибо, вы указали возможное решение. Я отправлю свой ответ ниже. –

ответ

1

current_user - это помощник, доступный только в режимах просмотра/контроллера. Вам нужно передать его в качестве параметра в модель. Кроме того, он недоступен в моделях. Может быть, это должно помочь.

0

В конце концов я закончил использовать обратный вызов after_create, но вместо того, чтобы получать данные из параметров, я использовал ассоциации. Также if @participant.nil? не работал по какой-либо причине.

class RatingAnswer < ActiveRecord::Base 
    belongs_to :rating_question 
    after_create :add_participant 
    ... 
    protected 
    def add_participant 
    @participant = Participant.where(:user_id => self.user.id, :survey_id => self.rating_question.survey.id) 
    unless @participant.any? 
     @new_participant = Participant.create(:user_id => self.user.id, :survey_id => self.survey.rating_question.id) 
    end 
    end 
end 

Прохладная вещь с ассоциациями, если у вас есть глубоко вложенные ассоциации для вместо

Survey has_many questions 
Question has_many answers 
Answer has_many responses 

с целью выборки обзорного идентификатора из внутри модели ответов вы можете сделать

self.answer.question.survey.id 

очень изящный!

Смежные вопросы