我有表格items
和cards
,其中一张卡属于user
,而item
可能有也可能没有给定用户的任何卡片。< / p>
基本关联设置如下:
Class User
has_many :cards
Class Item
has_many :cards
Class Card
belongs_to :user
has_and_belongs_to_many :items
我还创建了一个包含items_cards
和item_id
列的联接表card_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进行此操作的指导。谢谢!
答案 0 :(得分:1)
假设您在@item
中有一个项目,在@user
中有一个用户,如果该用户和该项目的卡片存在,则会返回'true':
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_id => @user
)指定的值。如果您将ActiveRecord对象作为值,则Rails将自动使用该对象的id。在这里,您说您只想要卡片属于您指定的用户的结果,并且您想要的项目有一行。
.exists?
- 加载ActiveRecord对象效率低下,因此如果您只想知道是否存在某些内容,Rails可以节省一些时间并使用基于count
的查询(非常类似于您的SQL版本)。还有.count
,如果您希望查询返回结果数,而不是true
或false
,则可以使用{{1}}。