[英]Rails check if HABTM association is changed
I have a roles table 我有角色表
select * from roles;
id | name
----+----------
1 | admin
2 | user
3 | author
4 | guest
5 | manager
and another table user_roles 和另一个表user_roles
select * from user_roles;
role_id | user_id
---------+---------
3 | 1
3 | 2
3 | 3
4 | 5
3 | 6
5 | 7
5 | 8
1 | 9
1 | 11
#role.rb
class Role < ActiveRecord::Base
has_and_belongs_to_many :users, join_table: 'user_roles', class_name: user_class.to_s
end
I am trying to do some actions when a user's role is updated say, from guest
to author
当用户的角色更新时,我试图做一些操作,从
guest
到author
#user.rb
class Use < ActiveRecord::Base
after_update :print_role_updated if: :user_roles_changed?
.
.
private
def user_roles_changed?
user_roles.any? { |role| role.changed? }
end
def print_role_updated
puts "User role changed from #{old_role} to #{new_role}"
end
end
But it is not working as expected ( .changed?
is checking whether the value in role
table is updated ?). 但它没有按预期工作(
.changed?
正在检查role
表中的值是否更新?)。
How do I run print_role_updated
method whenever user roles get updated to a diffrent one? 每当用户角色更新为不同的角色时,如何运行
print_role_updated
方法?
I tried Doctor's answer but role_updated?
我试过医生的答案,但是
role_updated?
is returning false even though the record is being updated 即使正在更新记录,也会返回false
class Use < ActiveRecord::Base
has_many :user_roles
after_update :print_role_updated if: role_updated?
.
.
private
def role_updated?
user_roles.any? {|a| a.changed?}
end
def print_role_updated
puts "User role changed from #{old_role} to #{new_role}"
end
end
try below code in model: 尝试下面的模型代码:
class User < ActiveRecord::Base
after_update :print_role_updated if: :user_roles_changed?
.
.
private
def print_role_updated
puts "User role changed"
end
def user_roles_changed?
u = User.find(self.id)
u.role != self.role # it check existing role and role saved in db
end
end
I think the _changed?
我觉得
_changed?
does only work for attributes not classes. 仅适用于属性而非类。 And since you have a many to many association you can't check on one object.
由于您有多对多关联,因此无法检查一个对象。 I would try something in this direction:
我会尝试朝这个方向努力:
if user_roles.any? {|a| a.changed?}
if a user only has a single role (sorry it is not clear from your code) then the following should work, or doesn't it ? 如果用户只有一个角色(很遗憾,您的代码中不清楚)那么以下内容应该有效,或者不是吗?
if user_roles.changed?
Update since you specified that a user can have many roles. 自您指定用户可以拥有许多角色以来的更新。 There should be a few corrections you should consider:
你应该考虑一些修正:
class Use < ActiveRecord::Base
has_many :user_roles
after_update :print_role_updated if: user_roles.any? {|a| a.changed?}
.
.
private
def print_role_updated
puts "User role changed from #{old_role} to #{new_role}"
end
end
Update 2: As it turns out, changed?
更新2:事实证明,
changed?
is false on newly created objects, so my previous update is not working. 在新创建的对象上为false,因此我之前的更新无效。
Try to change the changed?
尝试更改已
changed?
to the following: 以下内容:
user_roles.any? { |a| a.new_record? || a.marked_for_destruction? || a.changed? }
To be honest it is a bit a guessing I do here, but can you please try it? 说实话,我在这里做了一个猜测,但你可以试试吗? I would love to see if that works
我很想知道这是否有效
I found a solution. 我找到了解决方案。 the problem is that the HABTM relationship is updated in the db as soon as the new values are set
问题是,一旦设置了新值,就会在db中更新HABTM关系
here is my workaround for your example to implement an HABTM changed method. 这是我为您的示例实现HABTM更改方法的解决方法。 may not work for your exact case but knowing this you'll get the idea
可能不适用于您的确切情况,但知道这一点,你会得到这个想法
class User < ActiveRecord::Base
...
def user_role_ids=(ids)
@user_roles_changed = ids != user_role_ids
super(ids)
end
def user_roles_changed?
!!@user_roles_changed
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.