首先,我使用Rails 3.2.1和ruby 1.9.3p392
我有两个模型,ad_user和device
ad_user
有devices
个device
,而ad_user
属于class AdUser < ActiveRecord::Base
has_many :devices
class Device < ActiveRecord::Base
belongs_to :device_type
belongs_to :device_status
belongs_to :ad_user
validates_presence_of :name
validates_uniqueness_of :name
validates_presence_of :serial
validates_uniqueness_of :serial
validates_presence_of :device_type_id
validates_presence_of :device_status_id
validates_presence_of :ad_user_id
before_update :before_update_call
before_save :before_save_call
before_create :before_create_call
before_validation :before_validation_call
protected
def before_update_call
p self.name
p self.ad_user_id
p "-=-=-=-=-=-=-=-=-"
p "before_update_call"
self.ad_user_id = 1 if self.ad_user_id.nil? || self.ad_user_id.blank?
end
def before_save_call
p self.name
p self.ad_user_id
p "-=-=-=-=-=-=-=-=-"
p "before_save_call"
self.ad_user_id = 1 if self.ad_user_id.nil? || self.ad_user_id.blank?
end
def before_create_call
p self.name
p self.ad_user_id
p "-=-=-=-=-=-=-=-=-"
p "before_create_call"
self.ad_user_id = 1 if self.ad_user_id.nil? || self.ad_user_id.blank?
end
def before_validation_call
p self.name
p self.ad_user_id
p "-=-=-=-=-=-=-=-=-"
p "before_validation_call"
self.ad_user_id = 1 if self.ad_user_id.nil? || self.ad_user_id.blank?
end
。
我的模型如下:
u = AdUser.first
u.device_ids=[1,2]
当我使用
将设备分配给用户时before_validation_call
我可以看到before_save_call
,before_update_call
和u.device_ids=[]
打印到控制台,但是当我从用户取消分配这些设备时:
SQL (2.0ms) UPDATE "devices" SET "ad_user_id" = NULL WHERE "devices"."ad_user_id" = 405 AND "devices"."id" IN (332, 333)
结果很简单:
ad_user_id
尽管模型应该验证存在,但我的设备最终都没有被调用,并且我的设备最终没有ad_user_id
。我计划在保存或更新之前使用回调来检查{{1}}是否为零,但它们甚至都没有被调用。
我在这里做错了吗?
答案 0 :(得分:0)
不幸的是,我认为这是一种预期的行为。您不应该依赖于更新关联时触发的回调,因此隐式更新基础模型。
虽然您可以做什么,但请尝试访问devices
字段。 device_ids
在不同的级别上表现不同。
如果适合,请考虑使用association-callbacks。
P.S。只是一个小注意事项:在Rails中,您可以使用self.ad_user.present?
代替self.ad_user_id.nil? || self.ad_user_id.blank?
。此外,您可以合并validates_presence_of
语句。
答案 1 :(得分:0)
然后,在update
控制器的ad_user
方法中,在我添加的update_attributes
之前:
old_device_ids = @ad_user.device_ids
我添加update_attributes
之后:
(old_device_ids - AdUser.find(params[:id]).device_ids).each do |device|
Device.find(device).update_attributes(:ad_user_id => 1)
end
我之前已经做过,但我想找到一个合适的&#34; Rails方式&#34;这样做。