模型方法本身应该调用“保存”吗?

时间:2010-10-09 16:34:50

标签: ruby-on-rails ruby design-patterns

假设我们在模型中有一个方法

  1. 只需要保存记录
  2. 可能会更新模型本身,因此需要在“
  3. >之后再次保存模型”

    “save”调用是否应该在方法本身内部发生,如下面的代码

    def result
      save! if new_record?
    
      # do some funky stuff here that may also change the model state
      # ...
      # And calculate the return value
      search_result = "foo" # Let's say "foo" is the value we calculated
    
      save! if changed?
      search_result # return
    end
    

    或者外部观察者(控制者)是否应该负责根据需要调用保存?

3 个答案:

答案 0 :(得分:4)

如果你的方法确实需要做到这一切,那就这样吧。

但是,我会通过查看你为什么这样做的方法来说清楚(评论可能在这里很好),并且绝对使它成为bang_method!以便它很明显,无论谁调用它,这种方法都容易弄乱对象。

此外,方法名称result(我知道,可能不是您真正的方法名称)有点暗示您只是获取数据,而不是更多。也许load_result!在这里更合适,更清楚的是你不仅仅是访问一个属性,而且实际上是在执行繁重的操作来获取它。

答案 1 :(得分:4)

有时候模型必须坚持自己。但值得考虑的是 save 是否是您应用程序的最佳方法。

在当前示例中,我们有一个模型,它在长时间运行的方法中异步处理文件(我们使用sidekiq关闭进程。)在方法中,持久属性会定期更新,因此状态信息可用其他请求。

我们使用 update_column 而不是保存,因为

  1. 我们不希望或不需要AR回调的开销,我们特别想跳过验证以确保更新肯定会立即发生。
  2. 我们只需要更新一个属性。使用 update_column 可以避免确定是否需要保存(或不保存)任何其他属性。
  3. 在模型中,有像

    这样的方法
    • update_column
    • 保存(:validate => false) (已授予,方法相同,但选项不同)
    • 触摸

    等,通常可能是比普通保存更持久的更改方式。

答案 2 :(得分:2)

程序何时在文件上保存数据?

a)仅在用户需要时(直接或间接)? - 这是控制器案例

b)只有当程序实现部分正确性和数据完整性时? - 这是典型案例

c)两者。

我会投票赞成(c)。我希望这种歧视会使事情有所改善。

此外,从面向对象的设计角度来看,方法save()属于其类的公共契约;它可以被任何人调用。鉴于此,一个类负责其公共合同,如果需要,一个对象可以随意调用自己的方法。