如何在连接表中使用计数条件构造此连接?

时间:2009-11-20 20:10:49

标签: ruby-on-rails

我正在努力寻找“开放式”游戏,这些游戏是玩家开放的游戏。使用num_players创建游戏,代表该游戏的最大玩家容量。

游戏have_many玩家。

我尝试了以下

Game.find(:all, :include => :players, :group => 'players.game_id', :conditions => ['players.count(*) < games.num_players'])

但它不喜欢条件中的计数(*)

1 个答案:

答案 0 :(得分:2)

简短的回答是:

Game.find(:all, :include => :players, :group => 'players.game_id', 
  :select => "games.*, COUNT(players.id) AS players_count", 
  :conditions => "players_count < games.num_players"
  )

然而,这不是很干。从长远来看,您可能会发现使用计数器缓存设置该关系更容易。有关如何以及为何的详细信息,请参阅此railscast

设置计数器缓存是一个简单的三步过程。

  1. 将一个players_count整数列添加到Game。
  2. 更新所有现有游戏记录的players_count。
  3. :counter_cache => true添加到belongs_to :game声明。
  4. 然后找到所有公开游戏:

    Game.find(:all, :conditions => "games.players_count < games.num_players")
    

    制作指定范围的奖励点:

    class Game < ActiveRecord::Base
      has_many :players
    
      named_scope :open, :conditions => "games.players_count < games.num_players"
      named_scope :type, lambda {|type| 
        {:conditions => {:type => type}}
      }
      named_scope :baseball, :conditions => {:type => "baseball"}
    end
    
    Game.open # => Returns all open games.
    Game.baseball.open # => Returns all open baseball games.
    Game.open.type("football") # => Returns all open foot ball games.