ActiveRecord计算两个表的条​​件

时间:2009-09-29 17:59:20

标签: sql ruby-on-rails activerecord

在观看了最新的带有包含和连接信息的RailsCasts后,我知道我可以以更有效的方式做我正在做的事情。我有一个非常简单的用户模型和状态模型。用户属于状态,状态有许多用户。我需要计算有多少用户具有特定类型的状态,这会为每个状态创建一个新的SQL计数查询,我知道这不是一个好方法。它现在看起来像这样。

statuses = Status.all

statuses.each do |status|
  status.users.count
end

我最终得到了4个查询:

SELECT count(*) AS count_all FROM "users" WHERE ("users".status_id = 1)
SELECT count(*) AS count_all FROM "users" WHERE ("users".status_id = 2)

对于数据库中存在的许多不同状态,它会继续下去。最大的问题是现在我需要通过另一个协会过滤,即组织。所以我需要找到在某个组织中具有特定状态的所有用户的计数。这最终导致我查询的数量增加了四倍,并且感觉非常糟糕。我不确定我可以使用什么样的联接来减少这个或者我可以做些什么来解决这个问题。谢谢你的帮助:)

3 个答案:

答案 0 :(得分:2)

好的,我正在回答我自己的问题,以防万一有人遇到同样的问题。

Status.all(:joins => :users,
           :select => "statuses.*, count(users.id) as users_count",
           :group => "statuses.id")

这会将具有用户的每个状态和用户的计数返回为users_count。为了进一步细化查询并仅计算属于某个组织的用户,查询将更改为此。

Status.all(:joins => :users,
           :select => "statuses.*, count(users.id) as users_count",
           :conditions => {:users => {:organization_id => ORG_ID_HERE}},
           :group => "statuses.id")

我希望这可以帮助任何有同样问题的人,感谢Eimantas和Ryan Bates(RailCasts)。

答案 1 :(得分:1)

您可以尝试使用纯SQL:

SELECT s.name,COUNT(u.id) AS users_count FROM statuses s, users u WHERE s.id=u.status_id GROUP BY s.id;

答案 2 :(得分:0)

出于兴趣,您的状态模型包含哪些内容?它真的需要成为自己的模型吗?我在这里猜测,但你可能想考虑实施一个finite state machine。有许多轨道插件可以很容易地实现FSM,例如acts_as_state_machine