同时更新两个实例变量

时间:2013-03-25 03:30:44

标签: ruby-on-rails

我有一个带有User.rbQuestion.rbAnswer.rb模型的Rails应用程序。在每个模型之间定义可预测的关系。用户has_many提问,用户也has_many回答问题。问题has_many也会回答。

我试图让提问者选择答案为“best answer”。因此,我在Answers控制器中创建了一个'bestAnswer'控制器动作。在此控制器操作中,我希望在@question中存储最佳答案的ID,并指出特定@answer被选为最佳答案。因此,我同时为update_attributes@question尝试@answer

if @question.update_attributes(:accepted_answer_id => @answer.id) && @answer.update_attributes(:accepted => true)

完整的方法。

 def bestanswer


    @answer = Answer.find(params[:answer_id])
    @question = Question.find(params[:question_id])     
         if @question.update_attributes(:accepted_answer_id => @answer.id) && @answer.update_attributes(:accepted => true)
             redirect_to @question, notice: 'You have accepted as best answer' 
         else
             redirect_to @question, notice: 'There was a problem marking this as best answer. Please try again.' 
         end
 end 

这有效,但我也知道Rails支持事务。缺乏经验,我不确定我是否应该像上面那样做事,或者尝试做交易,或其他事情。如果您认为我应该进行交易,您会怎么写?我有点困惑,因为我认为交易应该在模型上完成,我不确定在模型中使用实例变量等,以及在哪个模型上编写它。

更新。我通过以下方式在第一个答案中实施了建议。它有效,但对我来说看起来很奇怪。由于我的OP询问了如何编写事务,我希望有人会澄清如何将事务集成到控制器操作中。

            if ActiveRecord::Base.transaction do
                      @question.update_attributes! :accepted_answer_id => @answer.id
                      @answer.update_attributes! :accepted => true
                    end
                 redirect_to @question, notice: 'You have accepted as best answer' 
             else
                 redirect_to @question, notice: 'There was a problem marking this as best answer. Please try again.' 
             end

1 个答案:

答案 0 :(得分:1)

你可以做到

ActiveRecord::Base.transaction do
  @question.update_attributes! :accepted_answer_id => @answer.id
  @answer.update_attributes! :accepted => true
end

我在这里使用!因为只有在发生异常时ActiveRecord才会回滚事务,如果出现问题,!版本的update_attributes将会触发。

此外,如果您在问题模型上设置了has_one :accepted_answer关系,则应使用

@question.update_attributes! :accepted_answer => @answer

而不是手动设置ID。通常,最好让ActiveRecord管理ID。