2016-08-30 3 views
2

現在の更新によって列ステータスの値が変更された場合のみ、通知用メールをレールアプリケーションで送信しようとしています。私はいくつかの投稿とstatus_changed?メソッドで提案されているように、Active Model Dirtyを使ってみました。残念ながら、@ partnership.status_changedのため、私のメールは送信されませんでしたか?最後の更新中に状態の値が実際に変更された場合でも、常にfalseを返します。ここに私のコントローラのコードは次のとおりです。私は間違って何をやっている最新の更新中に変更された属性の値がアクティブモデルで機能しないのを検出しました。

class Partnership < ActiveRecord::Base 
    include ActiveModel::Dirty 

def update 
    authorize @partnership 
    if @partnership.update(partnership_params) 
     send_notification_email 
     render json: {success: "partnership successfully updated"}, status: 200 
    else 
     render_error(nil, @partnership) 
    end 
    end 

    private 

    def send_notification_email 
    PartnershipMailer.partnership_status_change(@partnership).deliver_now if @partnership.status_changed? 
    end 

は、私はまた私のモデルで汚れたアクティブなモデルが含まれていましたか?

答えて

1

.updateも、データを更新した後にモデルを保存するため、ダーティー値がリセットされます。 .assign_attributesを使用してください。属性を割り当てるだけで、変更を確認し、最後にモデルを保存することを覚えておくことができます。

2

アクティブなレコードの変更された属性をチェックするためにこのメソッドを試すことができます。

@partnership.changed.include?("status") 

trueを返すと、このレコードで変更されたステータス属性があります。 @Thounderが指摘したように、あなたがレコードを保存するたびに、ActiveModel::Dirty方法<attribute>_changed?がリセットされ

after_commit :send_notification_email, if: Proc.new { |model| model.previous_changes[:status]} 
0

は、あなたのケースに最適なモデルにすることができます1つのライン方式です。したがって、保存間の変更のみを追跡します。

使用する場合は、previous_changesメソッドを使用します。このメソッドは、属性が変更されたキーと古い値と新しい値の配列である値を持つハッシュを返します。

person = Person.new(name: "Bob") 
person.name_changed? # => true 
person.save 
person.name_changed? # => false (reset when save called) 
person.previous_changes # => { name: [nil, "Bob"] } 
person.previous_changes[:name] # => returns a "truthy" statement if :name attribute changed 

私の擬似コードは間違っているかもしれませんが、原理は機能します。私はこれまでにこの "つかみ"に噛まれていました.Railsのコアチームがそれを変更してもらいたいと思います。

私は彼らの推論を理解していますが、保存後も<attribute>_changed?を追跡する方が理にかなっています。

2

:ここ

関連する問題