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

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

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。

共收到 3 条回复

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

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

classicalliu 回复

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

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