2012-01-04 21 views
0

私は新しいメソッドを定義したcountry.rbのメソッドを持っています。モデルの保存

class Country < ActiveRecord::Base 
    has_many :states, :dependent => :destroy 

    after_save :count_total_states 

    def count_total_states 
    self.duration = State.count(:conditions => { :country_id => self.id }) 
    Country.save!(:duration => self.duration) 
    end 
end 

私はself.durationの結果を得ました。私はそれを実行したときしかし、それは私が毎回新しい状態が作成されている国に属している、それは状態の数をカウントしたい

undefined method 'save!' for #<Class:0x111170d10>

を言いました。何をすべきかアドバイスしてください。ありがとう。

答えて

2

代わりにupdate_columnを使用してください。コールバックと検証をスキップします。ここにはupdate_columnのドキュメントがあります。

また、states.countには、国別に州を検索するためのクエリが用意されています。 has_many :statesはこれを可能にします。

class Country < ActiveRecord::Base 
    has_many :states, :dependent => :destroy 

    after_save :count_total_states 

    def count_total_states 
    update_column(:duration, states.count) 
    end 
end 
+0

なぜ私は 'after_save'を行う必要があるのですか?カウントを行う前に、新しい状態が保存されていることを確認したいからです。私が保存する前にカウントを行うと、新しい状態は含まれません。 – Victor

+0

ファイン。私の例を更新しました。 –

+0

それでも無限ループが発生しました... – Victor

0

それはこのようにする必要があります

def count_total_states 
    duration = State.count(:conditions => { :country_id => self.id }) 
    self.save!(:duration => duration) 
end 
+0

このソリューションは、部分的に正しいのみです。私の答えを見てください。 – Shreyas

+0

私は実際にそれを試みました。しかし、私はルビーのメモリリークを得て、それは私の自由なラムをすべて吸い込み、応答しません。 – Victor

+0

それは無限ループを引き起こすからです。 – Shreyas

0

こちらのミスのカップル。

  1. 救います!インスタンスメソッドなので、Country.save!仕事はしません(国はクラスです)。
  2. 保存しています。無限ループを引き起こすafter_saveコールバックによってトリガーされているメソッドで呼び出されます。

よりよい解決策は次のようになります。もちろん

class Country < ActiveRecord::Base 
    has_many :states, :dependent => :destroy 

    after_create :count_total_states 

    def count_total_states 
    self.duration = State.count(:conditions => { :country_id => self.id }) 
    self.save   
    end 
end 

をこのシナリオでbefore_saveコールバックを使用して別の利点は、あなたがそうでなければ起こったであろう追加のSQL(UPDATE ...)を保存しているありますafter_saveを使ってあなたのシナリオでは

EDIT

I want it to count number of states belong to the country everytime a new state is created. 

、上記のステートメントを与え、あなた以下のコメントはafter_createメソッドを使用する必要があります。

+0

なぜ私は 'after_save'を行う必要があるのですか?カウントを行う前に、新しい状態が保存されていることを確認したいからです。私が保存する前にカウントを行うと、新しい状態は含まれません。 – Victor

+0

シナリオでafter_saveを使用することはできません。なぜなら、私が言ったように、無限ループを引き起こすからです。私は私の答えを更新しました。 before_saveを使用しない場合は、after_createを使用します。 – Shreyas

+0

更新は実際に新しい状態を追加できるので、 'after_create:count_total_states'と' after_update:count_total_states'を一緒に使うことができますか?実際にはネストされたモデルです。私はちょうど私の質問でそれを簡素化します。 – Victor

関連する問題