2

プロジェクトを Rails 2.3.2 から 2.3.15 にアップグレードしています。はexists?ファインダと見なされるようになりました。つまり、 などの関数after_findは からのコールバックになりましたexists?

2.3.2exists?では、 へのコールバックがトリガーされませんでしたafter_find。ポリシーでこの変更を明示的に指定している github のコミット以外に、読み取り可能な変更ログを見つけるのに苦労しています。

exists?誰かが 2.3.2では呼び出しを行わずafter_find(存在する必要があります)、2.3.15 では呼び出しを行うことを確認できますか?

この場合、after_find呼び出しを分離するためのクリーンな Rails の方法はありますか? .の後ではなく、真の検索の後に実行されるコードが必要ですexists?

一時的な回避策として、これをモデルの最初の行にすることを試していますafter_find:

return unless self.has_attribute?(:some_attrib_your_model_uses_in_after_find)
4

2 に答える 2

0

これを行う方法は 3 つありますが、どれも満足のいくものではありませんが、少なくとも 2 つは確実に機能します。

A) 使用する属性が欠落している場合に返す

def after_find
  # What a flaky way to ruin your code:
  return unless self.has_attribute?(:some_attrib_your_model_uses_in_after_find)
  @amazing_pain = @some_attrib_your_model_uses_in_after_find + 1
end

B) コールスタック全体を grep する

(そして、存在することを祈りますか?あなたがそう思うので、そこにあります)

これをオプションとして投稿するのは恥ずかしいですが、 で使用できる文字列の配列で何ができるかを見るのは良いことですcallercallerフォーマットが変更されないことを願いましょう。

コンソールから 2.3.15 を使用すると、モデルの after_find() へのコールスタックは次のようになります。

/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/callbacks.rb:347:in `send'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/callbacks.rb:347:in `callback'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/base.rb:1687:in `send'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/base.rb:1687:「インスタンス化」
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/base.rb:665:`find_by_sql'内
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/base.rb:665:in `collect!' で
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/base.rb:665:`find_by_sql'内
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/base.rb:1582:`find_every' 内
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/base.rb:1539:`find_initial' 内
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.15/lib/active_record/base.rb:696:「存在しますか?」
(irb):2:in `irb_binding'
/usr/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'
/usr/lib/ruby/1.8/irb/workspace.rb:52

C) モデルを Eager-Load にする

2.3.15 ActiveRecord README がそれを示唆しているので、これをやりたいと思う人もいるかもしれません:

after_find :eager_load, 'self.class.announce(#{id})'

必要以上に DB に負担をかけたくありません。多くの場合の呼び出しのポイントはexists?、単純な単一列のルックアップを行うことです。exists?呼び出しを行うためだけに、モデル全体と、場合によってはその関連付けの熱心な読み込みを実行すると、パフォーマンスが低下します。

于 2013-01-16T18:25:00.287 に答える
0

この答えはまったく役に立ちますか?

rails3 へのアップグレード後に after_find コールバックが壊れた

head rails 2.3 ブランチは、rails 3 に存在するものに近いはずです。このような大きな変更の多くは、2.3.12 または 2.3.14 の頃に発生したと思います。IIRC これは、Rails 3 へのアップグレードを容易にするために行われました。

于 2013-01-16T18:53:50.523 に答える