1

私のモデルは次のようになります。

class Movie < ActiveRecord::Base
  attr_accessible :title, :year, :rotten_id, :audience_score,
    :critics_score, :runtime, :synopsis, :link, :image

  has_many :jobs, :dependent => :destroy
  has_many :actors, :through => :jobs
end

class Actor < ActiveRecord::Base
  attr_accessible :name
  has_many :movies, :through => :jobs
  has_many :jobs, :dependent => :destroy
end

class Job < ActiveRecord::Base
  attr_accessible :movie_id, :actor_id

  belongs_to :movie
  belongs_to :actor
end

俳優のインデックスを表示するときに、各俳優が主演した映画の数を表示したいと思います。これはで実行できますが@actor.movies.count、これにより、のSQLクエリが生成されますeach actor。たとえば、アクターが30人の場合、これにより、イニシャルに加えて30個の追加クエリが発生します。

Actor.all各俳優が参加した映画の数を最初の電話に含める方法はありますか?そしてそれにより、たった1回の呼び出しで物事を成し遂げることができます。これが上記のカウントでソートされている場合、追加のボーナス。

更新: 提供されたすべての回答は役に立ちました。ある時点でダートスリングコンテストになりましたが、うまくいきました。私はあなたのすべての提案のミッシュマッシュをしました。アクターモデルにmovies_counter列を追加しました。私のジョブモデルに追加しましbelongs_to :actor, :counter_cache => :movies_counterた。これは見事に機能し、ムービーを作成または破棄すると、コードを追加しなくても自動的に更新されます。

4

2 に答える 2

2

@Samが気付いたように、actorsテーブルに新しい列を追加する必要がありますmovies_counter

rails g migration add_movies_counter_to_actor movies_counter:integer

これで、移行を編集できます

class AddMoviesCounterToActor < ActiveRecord::Migration
  def self.up
    add_column :actors, :movies_counter, :integer, :default => 0

    Actor.reset_column_information
    Actor.all.each do |a|
      a.update_attribute :movies_counter, a.movies.count
    end
  end

  def self.down
    remove_column :actors, :movies_counter
  end
end

そしてそれを実行します

rake db:migrate

次に、2つのコールバックを追加する必要がありますafter_saveafter_destroy

class Movie < ActiveRecord::Base
  attr_accessible :title, :year, :rotten_id, :audience_score,
    :critics_score, :runtime, :synopsis, :link, :image

  has_many :jobs, :dependent => :destroy
  has_many :actors, :through => :jobs

  after_save :update_movie_counter
  after_destroy :update_movie_counter

  private
  def update_movie_counter
    self.actors.each do |actor|
      actor.update_attribute(:movie_count, actor.movies.count)
    end
  end
end

その後、あなたは呼び出すことができますsome_actor.movies_counter

于 2011-03-19T21:54:36.890 に答える
0

'movie_count'という列をActorテーブルに追加します。次に、その列を更新するコールバックをアクターモデルに追加します。

class Movie < ActiveRecord::Base
  has_many :actors, :through => :jobs
  before_save :update_movie_count
  def update_movie_count
     self.actor.update_attribute(:movie_count, self.movies.size)
  end
end

そうすれば、すべてのレコードを呼び出す代わりに、更新される整数を使用できます。

于 2011-03-19T21:55:20.343 に答える