2013-02-18 48 views
0

我有表itemscards其中卡属于useritem可能或可能没有任何给定用户的卡。Rails:多对一(0 - n),查找记录

基本的关联被设置如下:

Class User 
    has_many :cards 

Class Item 
    has_many :cards 

Class Card 
    belongs_to :user 
    has_and_belongs_to_many :items 

我还创建了一个连接表,items_cards与列item_idcard_id。我想做一个查询,告诉我是否有给定用户/项目的卡片。在纯SQL中,我可以很容易地完成:

SELECT count(id) 
FROM  cards 
JOIN  items_cards 
ON  items_cards.card_id = cards.id 
WHERE cards.user_id = ? 
AND  items_cards.item_id = ? 

我正在寻找一些关于如何通过ActiveRecord执行此操作的指导。谢谢!

回答

1

假设你已经在@item一个项目,并在@user用户,这将返回“真”,如果存在该用户的卡和项目:

Card.joins(:items).where('cards.user_id = :user_id and items.id = :item_id', :user_id => @user, :item_id => @item).exists? 

这里的是怎么回事:

Card. - 您正在查询卡片模型。

joins(:items) - Rails知道如何为它支持的关联类型(通常 - 至少)组合连接。你告诉它做任何需要的连接,以便你可以查询关联的items。在这种情况下,这将导致JOIN items_cards ON items_cards.card_id = cards.id JOIN items ON items_cards.item_id = items.id

where('cards.user_id = :user_id and items.id = :item_id', :user_id => @user, :item_id => @item) - 您的条件式,与纯SQL几乎相同。 Rails会使用冒号(:user_id => @user)中的值插入用冒号(:user_id)指定的值。如果您将ActiveRecord对象作为值,则Rails将自动使用该对象的ID。在这里,你说的只是卡片属于你指定的用户的结果,并且你想要的物品有一行。加载ActiveRecord对象效率低下,因此如果您只想知道是否存在某些事情,Rails可以节省一些时间并使用基于count的查询(与您的SQL版本非常相似)。还有一个.count,如果您希望查询返回结果数而不是truefalse,则可以使用它。