0

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

我正在尝试为提问者提供选择答案作为“ best answer”的选项。因此,我在 Answers 控制器中创建了一个“bestAnswer”控制器操作。在此控制器操作中,我希望将最佳答案的 id 存储在 中@question,并指示该特定@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
4

1 回答 1

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 模型上设置了关系,则应使用

@question.update_attributes! :accepted_answer => @answer

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

于 2013-03-25T04:18:33.567 回答