Rails 回调 before_update 的误区

torvaldsdb · 发布于 2016年9月21日 · 最后由 hging 回复于 2016年9月24日 · 983 次阅读
19780

before_update

如果想在该回调函数中重新更新对象的属性,这时候要避免使用update或者update_attributes, 换一个方法使用update_column

update_column这个方法提供

  • Validations are skipped.(跳过验证)
  • Callbacks are skipped.(跳过回调)
  • updated_at/updated_on are not updated.(两个字段不再更新)

这样可以避免before_update的死循环.

  • save(validate: false)可以跳过验证
共收到 10 条回复
11562

。。。然后就一堆脏数据。。 其实讲道理在before_update里面不应该直接更新数据 直接指定就好。 然后后面会自动更新的。 这样即保证了数据的完整性又实现了效果。

20859

after_save也有个不太容易被注意的小坑

如果after_save里用了sidekiq,那么可能该数据被commit到数据库前sidekiq就会去取它

19780

#1楼 @hging 直接指定 具体一下嘛 我最后用update_column解决的...也觉得很不妥.不过放弃安全问题,可用非最好.

11562

#3楼 @torvaldsdb 比如你直接这么写

def set_username
    self.username = "xxxx"
end

这样就行了啊。 没必要在before_update 的时候直接update

3035

before_update 中去 update 这条数据本身么?按4楼那样赋值就好了 另外我有点好奇 update_column 应该会直接写数据库然后返回新的对象吧,你这样是不是会有两条数据库写入操作?

#2楼 @adamshen 这个问题是不是 after_save 和 after_commit 行为差异的那个坑,之前看文章提到 5 里会修复,也不知道修了没😂

19780

#4楼 @hging

我开始是按照你给出的这样子写的,可是我遇见了下面的问题

我用到after_create与before_update,然后两个方法里面重复代码太多我就想复用一下重复的代码,然后更新了相同的属性.你提出来的那种直接赋值,不能在after_create中良好嵌用.所以我曲线救国的选用了update_column.

19780

#5楼 @IChou 好像是个问题...我还是测试一下吧

11562

#6楼 @torvaldsdb 所以。 为什么会同时使用after_create与before_update 并且会有重复代码。 这个是比较关键的问题。 要理清楚逻辑,尽可能简化,甚至说可以在共用代码中使用new_record?这种方法。 判断是在更新还是创建。

19780

#8楼 @hging 需要处理对象的id,也就是一个中间表需要该表的id作为外键,如果不是after_create该对象的id是nil无法处理外键的问题

11562

#9楼 @torvaldsdb 一个中间表的话 处理可以直接用has_many这种model关联关系进行创建啊 不需要手工处理id啊

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册