Rails 3.2.1 关联没有回调



首先,我使用的是 Rails 3.2.1 和 ruby 1.9.3p392

我有两种型号,ad_user和设备

一个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_callbefore_save_callbefore_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是否为零,但它们甚至没有被调用。

我在这里做错了什么吗?

不幸的是,我认为这是预期的行为。更新关联时不应依赖触发的回调,因此将隐式更新基础模型。

不过,您可以做的是尝试访问devices字段。 device_ids在较低水平上表现不同。

如果合适,还可以考虑使用关联回调。

附言只是一个小说明:在 Rails 中您可以使用 self.ad_user.present? 而不是 self.ad_user_id.nil? || self.ad_user_id.blank? .此外,还可以合并validates_presence_of语句。

好吧,在我的ad_user控制器的update方法中,在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

我之前已经这样做了,但我想找到一种合适的"Rails 方式"。

最新更新