Rails Active Record 中 many to many 遇到的问题记录

zhangbin-github for 时空 · 2018年01月18日 · 最后由 zhangbin-github 回复于 2018年01月19日 · 1483 次阅读

rails-guides 中有关于 many to many 的具体文档

https://ruby-china.github.io/rails-guides/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many

我最近有一个需求,就是每次更新以后,需要保留一个 history。

举例:

有一个 model:User,一个 model:UserHistory,还有 model:Role,User 和 Role 是多对多的关联。

class User < ApplicationRecord
  has_many :users_role
  has_many :roles, through: :users_role
end

class Role < ApplicationRecord
  has_many :users_role
  has_many :users, through: :users_role
end

# 有一列role_ids,将当时用户关联的role id以字符串的形式保存
class UserHistory < ApplicationRecord
end

每次更新 user 时,需要将 user 对象的记录同步到 user_history 中,我采用的做法时,在 user 中增加一个 after_save 的 callback。

# in user.rb

  after_save: backup_to_history

  private
  def backup_to_history
    UserHistory.create(role_ids: roles.pluck(:id).join(';'))
  end

这里在 console 中测试的时候发现一个问题。

如果采用 << append 数组,是无法保存 role_ids 的

user.roles << Role.last

因为<<是一个独立的操作,从方法定义来看,也是 append 的意思,并不会删除原先已经存在的 role_ids。 如果需要更新 user 的 roles,必须采用 update 的方法

user.update(role_ids: Role.last(2).pluck(:id))

这样,不仅能够修改原先用户的 roles,还能在 call back 中保存住 role_ids。

如果采用 << append 数组,是无法保存 role_ids 的

没看懂这句话是什么意思,无法保存难道不是因为没有 save 么……

classicalliu 回复

我表达的有点问题,因为需求需要在历史记录中保存关联的 ids,<< 操作只会在关联表中追加,并不会触发 user 的更新动作,就无法在 history 中保存 ids 了。另外 << 是追加操作,也就不会删除已经取消关联的 role_id.

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