2017-12-05 18 views
0

ドキュメントをコーディネートした後、使用するコールバックを理解するのが難しいです。Rails ActiveRecordコールバック:存在する場合に更新する、存在しない場合に作成する

擬似コード:child_id場合

とoutage_idが

変更を変更した場合の関係(INSERT文)を作成

存在しませんoutage_id関係(UPDATEステートメント)

これらの挿入と更新は3つのモデルがありcollection_check_boxes

を介して処理されています。関係、停電、および子供。

class Outage < ApplicationRecord 
    has_many :relationships 
    has_many :children, through: :relationships 
end 

class Child < ApplicationRecord 
end 


class Relationship < ApplicationRecord 
    belongs_to :outage 
    belongs_to :child 

    validate :check_if_exists, if: :outage_id_changed? 

    private 

    def check_if_exists 
    Relationship.where(child_id: self.child_id).update_all(outage_id: self.outage_id) 
    end 
end 

私が今直面してる問題はUPDATEは常に、どんな権利INSERT前に発生していないということです。 UPDATEは、レコードが存在し、outage_idが変更された場合にのみ発生します。

私がここで間違っていることについての洞察は、わかります。あなたはこれを試すことができ

+0

ここで 'after_save'フックを見るとレコードの' saved_changes'にアクセスしてそのロジックを構築できます新しい属性と比較して – neongrau

+0

@neongrauありがとう、それを検討します。 – DnfD

答えて

0

class Relationship < ApplicationRecord 
    before_update :check_if_exists, if: :outage_id_changed? 

    private 
    def check_if_exists 
     # Your logic 
    end 
end 

注:あなたのコードのcheck_if_existsでが作成outage_idので、中に<some_id>nilから変更され、また、作成上で実行されます

しかしbefore_updateを使用することを確認します更新時にのみ実行すること

また、update_allを使用していることに注意してくださいダイレクトdbクエリであり、トランザクションでラップされません。意味は、すべての更新が失敗した場合、update_allによる変更はロールバックされません

+0

'nil'に良い点があります。しかし、 'UPDATE'アクションは認識されていません。これは、' update_all'で問題を強制しない限り、常に挿入されます。だから私は 'collection_check_boxes'を使うたびに' INSERT'と見なします。レポ:https://github.com/ornerymoose/TestAppForStackOverflow – DnfD

関連する問題