0

我有桌子itemscards卡片属于 a 的地方user,而 aitem可能有也可能没有给定用户的任何卡片。

基本关联设置如下:

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 执行此操作的指导。谢谢!

4

1 回答 1

1

假设您有一个 Item in@item和一个 User in @user,如果该用户和该项目存在一张卡片,这将返回“true”:

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

这是发生了什么:

Card.- 您正在查询 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 中的几乎相同。:user_idRails 将使用散列 ( ) 中的值插入带有冒号 ( ) 的值:user_id => @user。如果您将 ActiveRecord 对象作为值,Rails 将自动使用该对象的 id。在这里,您说您只想要卡片属于您指定的用户的结果,并且您想要的项目有一行。

.exists?- 加载 ActiveRecord 对象是低效的,所以如果你只想知道某些东西是否存在,Rails 可以节省一些时间并使用count基于查询(很像你的 SQL 版本)。还有一个.count,如果您想让查询返回结果的数量,而不是trueor ,您可以使用它false

于 2013-02-18T18:30:04.660 回答