我的设置:Rails 2.3.10,Ruby 1.8.7
我需要为事务更新模型的多个实例。我应该创建一个类方法并更新方法中的所有实例,还是应该将该逻辑移动到控制器并通过模型的实例方法更新每个实例?我想这是脂肪控制器和脂肪模型之间的权衡,一般的建议是脂肪模型超过脂肪控制器。
答案 0 :(得分:2)
都不是。如果它是一个重要的逻辑,为什么不将它合并到一个专门的类?
或者,如果您(我假设)表单数据可以这样配置:
params[:models] = { id_of_instance_1 => { :attribute => value },
id_of_instance_2 => { :attribute => value2 },
}
您可以通过以下方式轻松地在控制器中进行组更新:
Model.update(params[:models].keys, params[:models].values)
有关您正在更新的详细信息以及它们来自哪里的详细信息可能有所帮助。
编辑:在阅读下面的回复后......
有几种方法可以做到。您可以实现Model.win
和Model.lose
作为类方法来合并逻辑,然后只需从控制器中调用这些方法:
def process_outcome
@winner = Model.win(params[:winning_id])
@loser = Model.lose(params[:losing_id])
end
或者,即使是单个方法调用:
def process_outcome
# passing the entire params hash to `process_outcome` which returns an array
@winner, @loser = Model.process_outcome(params)
end
就个人而言,如果涉及的唯一子对象是同一模型的所有实例,我将在类本身内实现此逻辑。
但是,如果您将各种类别混合在一起,则可能值得将其封装到一个单独的对象中:
# app/controllers/models_controller.rb
def process_outcome
@outcome_processor = OutcomeProcessor.new(params)
@winner = @outcome_processor.winner
@loser = @outcome_processor.loser
end
无论哪种方式,您的实际交易块都应该不在Controller中。
答案 1 :(得分:0)
我认为你应该遵循传统。 :) 您可以使用其他类(非控制器)来编写事务方法。
答案 2 :(得分:0)
它几乎肯定会进入模型,而不是控制器。
我认为应该使用实例方法,而不是类方法。我的理由是你可能会通过网址/model/id/action?other_model_id=other_id
来调用它。然后,在控制器操作中,您将获得id
的适当模型实例以及other_id
,但由于这是id
模型的路径,而不是other_id
模型{1}}模型,您可以调用@id_model.perform_action(@other_id_model)
。
希望这是有道理的。