Domanda

I miei modelli sembrano così:

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

Quando mostro il mio indice di attori, vorrei mostrare il numero di film ogni attore ha recitato. Posso farlo con @actor.movies.count, Tuttavia, questo genera una query SQL per each actor. Con, diciamo, 30 attori, ciò comporterà 30 domande extra oltre alle iniziali.

Esiste un modo per includere il conteggio dei film a cui ogni attore ha partecipato, nella iniziale Actor.all chiamata? E quindi fare le cose con una sola chiamata. Bonus extra se questo è stato ordinato con detto conteggio.

Aggiornare:Tutte le risposte fornite sono state utili e sebbene si sia trasformata in un po 'di slitting a un certo punto, ha funzionato bene. Ho fatto un miscuglio di tutti i tuoi suggerimenti. Ho aggiunto una colonna Film_Counter al mio modello attore. Nel mio modello di lavoro ho aggiunto belongs_to :actor, :counter_cache => :movies_counter. Funziona brillantemente e viene automaticamente aggiornato quando creo o distruggo un film, senza che io aggiunga ulteriore codice.

È stato utile?

Soluzione

Come ha notato @Sam, dovresti aggiungere una nuova colonna a actors tavolo movies_counter

rails g migration add_movies_counter_to_actor movies_counter:integer

Ora puoi modificare la tua migrazione

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

E eseguilo

rake db:migrate

Quindi dovresti aggiungere due callback: after_save e after_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

Quindi puoi chiamare some_actor.movies_counter

Altri suggerimenti

Aggiungi una colonna al tavolo dell'attore chiamato "Movie_Count". Quindi aggiungi una chiamata nel modello del tuo attore che aggiorna quella colonna.

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

In questo modo hai solo un numero intero che viene aggiornato invece di chiamare tutti i record.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top