0

由于我使用“updated_at”的性质(特别是在原子提要中使用),我需要避免在保存记录而没有任何更改的情况下更新 updated_at 字段。为了做到这一点,我阅读并最终得到以下内容:

module ActiveRecord
    class Base

    before_validation :clear_empty_strings

    # Do not actually save the model if no changes have occurred.
    # Specifically this prevents updated_at from being changed
    # when the user saves the item without actually doing anything.
    # This especially helps when synchronizing models between apps.
    def save

        if changed?
            super
        else
            class << self
                def record_timestamps; false; end
            end
            super
            class << self
                remove_method :record_timestamps
            end
        end

    end

    # Strips and nils strings when necessary
    def clear_empty_strings
        attributes.each do |column, value|
            if self[column].is_a?(String)
                self[column].strip.present? || self[column] = nil
            end
        end
    end

    end
end

这适用于我的所有模型,除了我的电子邮件模型。一封电子邮件可以有多个发件箱。发件箱基本上是一个两列模型,其中包含一个订阅者(电子邮件收件人:)和一封电子邮件(发送给订阅者的电子邮件)。当我更新发件箱的属性然后保存电子邮件时,我在保存时收到(参数 1 代表 0)错误(它指向保存方法中的“超级”调用)。

电子邮件.rb

has_many :outboxes, :order => "subscriber_id", :autosave => true

发件箱.rb

belongs_to :email, :inverse_of => :outboxes
belongs_to :subscriber, :inverse_of => :outboxes
validates_presence_of :subscriber_id, :email_id
attr_accessible :subscriber_id, :email_id

更新:我还注意到,当我更改关联模型时,没有填充“更改”数组。

@email.outboxes.each do |out|
    logger.info "Was: #{ out.paused }, now: #{ !free }"
    out.paused = !free
end unless @email.outboxes.empty?
@email.save # Upon saving, the changed? method returns false...it should be true
4

1 回答 1

0

...叹。在花了无数小时试图找到解决方案后,我遇到了这个。我是否知道“保存”方法实际上需要一个参数,我会更早地弄清楚这一点。显然在这方面查看源代码并没有帮助。我所要做的就是在 save 方法中添加一个 args={} 参数并将其传递给“super”,现在一切正常。保存未修改的记录而不更新时间戳,修改的记录与时间戳一起保存,并且保存关联没有错误。

module ActiveRecord
    class Base

    before_validation :clear_empty_strings

    # Do not actually save the model if no changes have occurred.
    # Specifically this prevents updated_at from being changed
    # when the user saves the item without actually doing anything.
    # This especially helps when synchronizing models between apps.
    def save(args={})

    if changed?
        super args
    else
        class << self
        def record_timestamps; false; end
        end
        super args
        class << self
        remove_method :record_timestamps
        end
    end

    end

    # Strips and nils strings when necessary
    def clear_empty_strings
    attributes.each do |column, value|
        if self[column].is_a?(String)
        self[column].strip.present? || self[column] = nil
        end
    end
    end
end
于 2013-02-19T17:01:50.450 回答