Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 避免单个数据库调用计数_Sql_Ruby On Rails_Ruby_Counter Cache - Fatal编程技术网

Sql 避免单个数据库调用计数

Sql 避免单个数据库调用计数,sql,ruby-on-rails,ruby,counter-cache,Sql,Ruby On Rails,Ruby,Counter Cache,我的模型是这样的: 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 e

我的模型是这样的:

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
class电影:销毁
有很多:演员,:到=>:工作
结束
类Actor:工作
拥有多个:作业,:依赖=>:销毁
结束
类作业
当我显示演员索引时,我想显示每个演员主演的电影数量。我可以使用
@actor.movies.count
,但是这会为每个演员生成一个SQL查询。假设有30个参与者,这将导致在初始查询之外增加30个查询

在最初的
actor.all
call中,是否有办法包括每位演员参与的电影数量?因此,只需一个电话就能完成任务。如果按上述计数排序,则可获得额外奖金

更新:
提供的所有答案都很有帮助,尽管在某个时候它变成了一场诽谤比赛,但效果很好。我把你所有的建议都弄糟了。我在我的演员模型中添加了一个电影计数器列。在我的工作模型中,我添加了
属于:actor,:counter\u cache=>:movies\u counter
。它工作得非常出色,在我创建或销毁电影时会自动更新,而无需添加任何进一步的代码。

正如@Sam所注意到的,您应该在
演员
电影\u计数器中添加新列

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
然后您应该添加两个回调:
after\u save
after\u 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
class电影:销毁
有很多:演员,:到=>:工作
保存后:更新电影计数器
销毁后:更新电影计数器
私有的
def更新电影计数器
自我演员。每个人都做演员|
actor.update\u属性(:movie\u count,actor.movies.count)
结束
结束
结束

然后您可以调用某个演员。电影计数器

在演员表中添加一个名为“电影计数”的列。然后在参与者模型中添加一个回调来更新该列

rails g migration add_movies_counter_to_actor movies_counter:integer
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
class电影:工作
保存前:更新电影计数
def更新电影计数
self.actor.update_属性(:movie_计数,self.movies.size)
结束
结束

这样一来,你就只需要更新一个整数,而不是调用所有记录。

我会在我的工作模型中进行更新电影计数,对吗?因为一部电影有几个演员,而且直到创造了一个工作岗位,演员的数量才应该增加。但我明白了。当您像之前一样了解实用程序时,这是一个简单的解决方法。Thanks@sam您正在重新实现计数器缓存功能。@sam实际上它在这里不太起作用,所以您必须重新实现它。@Adam Lassek。此外,正如@flOOr所指出的,您删除的答案是错误的,因为这是一个“已完成”的问题,所以我不会重新实现计数器缓存。如前所述,计数器缓存不起作用。。。但是:counter\u sql的一些实现会起作用吗?您正在重新实现counter\u缓存功能。这里有很多:通过关联,但没有counter\u缓存选项。您是对的,这看起来是最好的解决方案,尽管您可能应该使用
Actor.increment\u counter
,而不是每次进行完整计数。@Adam,它可以是递增或递减(删除时)。所以我们可以为每个回调编写两个方法,分别使用
increment\u counter
decrement\u counter
,或者我们可以使用这个解决方案,它有一个以上的sql请求,但如果项目不是高负载的话,它并不重要