0

コールバックをコメントアウトするafter_saveと、ActiveRecordの関連付けは問題なく機能します。Railsコンソールでは、次のように表示されます。

> @report = Report.create :name => "foo"
=> #<Report id: 9, name: "foo", created_at: "2013-03-05 09:51:55", updated_at: "2013-03-05 09:51:55"> 
> @question = @report.questions.create :description => "bar"
=> #<Question id: 18, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 09:52:32", updated_at: "2013-03-05 09:52:32", additive: false, instructions: nil> 
> @report.questions
=> [#<Question id: 18, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 09:52:32", updated_at: "2013-03-05 09:52:32", additive: false, instructions: nil>] 
> @question.reports
=> [#<Report id: 9, name: "foo", created_at: "2013-03-05 09:51:55", updated_at: "2013-03-05 09:51:55">]

after_saveただし、次のコールバックをに追加すると、関連付けが機能しなくなりquestion.rbます。

  def create_matching_surveys
    self.reports.each do |report|
      report.reviews.each do |review|
        review.competitors.each do |competitor|
          competitor.surveys.find_or_create_by_question_id(self.id)
        end
      end
    end
  end

次に、Railsコンソールで次のようになります。

> @report = Report.create :name => "foo"
=> #<Report id: 13, name: "foo", created_at: "2013-03-05 10:20:51", updated_at: "2013-03-05 10:20:51">
> @question = @report.questions.create :description => "bar"
=> #<Question id: 24, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 10:21:02", updated_at: "2013-03-05 10:21:02", additive: false, instructions: nil> 
> @report.questions
=> [#<Question id: 24, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 10:21:02", updated_at: "2013-03-05 10:21:02", additive: false, instructions: nil>] 
> @question.reports
=> [] 

これは、レポートに競合他社のレビューがあるかどうかに関係なく発生します。

奇妙なことに、質問が保存された後にコールバックが発生することを意図していたと思いましたか?ですから、権利によって、これが起こる前に協会も救うべきですよね?

どうすれば修正できますか?

アップデート

オブジェクトのライフサイクルの適切な場所でコールバックを呼び出す必要があると思いますが、その場所を見つけることができません。これが私がこれを考える理由です:

> @report = Report.create :name => "foo"
=> #<Report id: 20, name: "foo", created_at: "2013-03-05 12:29:35", updated_at: "2013-03-05 12:29:35"> 
> @question = @report.questions.create :description => "bar"
=> #<Question id: 31, standard_id: nil, description: "bar", element_id: nil, condition_id: nil, blueprint_name: nil, blueprint_url: nil, created_at: "2013-03-05 12:30:14", updated_at: "2013-03-05 12:30:14", additive: false, instructions: nil> 
> @question.reports
 => [] 
> @question.update_attributes :description => "foo"
=> true 
> @question.reports
=> [#<Report id: 20, name: "foo", created_at: "2013-03-05 12:29:35", updated_at: "2013-03-05 12:29:35">] 

ところで、メソッドは現在question_observer.rbにあります:

class QuestionObserver < ActiveRecord::Observer

  def after_save(model)
    model.reload
    model.reports.reload
    model.reports.each do |report|
      report.reviews.each do |review|
        review.competitors.each do |competitor|
          competitor.surveys.find_or_create_by_question_id(model.id)
        end
      end
    end
    return true
  end

end
4

1 に答える 1

0

after_commitその答えは、Rails 3 で導入された と呼ばれるきちんとした新しいコールバック フックを使用することでした。

http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#method-i-after_commitを参照してください。

唯一の問題はafter_commit、トランザクション フィクスチャで「すぐに」動作しないことですが、そこにはたくさんのソリューションがあり、これがうまく機能することがわかりました。 /14/testing-after_commitafter_transaction-with-rspec/

于 2013-03-06T02:54:11.767 に答える