我有一个带有User.rb
,Question.rb
和Answer.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
答案 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。