0

'updated_at'(特にAtomフィードで使用するため)の使用の性質上、レコードが変更なしで保存されるときに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

これは、Eメールモデルを除くすべてのモデルで正常に機能します。電子メールには多くの送信トレイを含めることができます。送信トレイは基本的に、サブスクライバー(Eメールの宛先:)とEメール(サブスクライバーに送信するEメー​​ル)を保持する2列のモデルです。送信トレイの属性を更新してからEメールを保存すると、保存時に(引数1 for 0)エラーが発生します(saveメソッドの「super」呼び出しを指します)。

Email.rb

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

Outbox.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'メソッドが実際に引数を取ることを私は知っていましたが、これはもっと早く理解できたでしょう。どうやらソースを見てもその点では役に立たなかったようです。私がしなければならなかったのは、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 に答える