5

我想知道从 has_many :through 关联中的连接模型中选择属性的最简单/最优雅的方法是什么。

假设我们有具有以下 Item 类的 Items、Catalogs 和 CatalogItems:

class Item < ActiveRecord::Base
      has_many :catalog_items
      has_many :catalogs, :through => :catalog_items
end    

此外,假设 CatalogueItems 具有位置属性,并且任何目录和任何项目之间只有一个 CatalogueItem。

检索位置属性的最明显但有点令人沮丧的方法是:

@item         = Item.find(4)
@catalog      = @item.catalogs.first
@cat_item     = @item.catalog_items.first(:conditions => {:catalog_id => @catalog.id})
position      = @cat_item.position

这很烦人,因为我们似乎应该能够做到@item.catalogs.first.position,因为我们已经完全指定了我们想要的位置:对应于@item 目录的第一个位置。

我发现得到这个的唯一方法是:

class Item < ActiveRecord::Base
      has_many :catalog_items
      has_many :catalogs, :through => :catalog_items, :select => "catalogue_items.position, catalogs.*"
end

现在我可以做 Item.catalogs.first.position。但是,这似乎有点像 hack - 我正在向 Catalog 实例添加一个额外的属性。它还开辟了尝试在两种不同情况下使用视图的可能性,其中我使用 Catalog.find 或 @item.catalogs 填充 @catalogs。在一种情况下,职位会在那里,而在另一种情况下,它不会。

有没有人对此有很好的解决方案?

谢谢。

4

4 回答 4

0

你可以这样做:

# which is basically same as your "frustrating way" of doing it
@item.catalog_items.find_by_catalogue_id(@item.catalogs.first.id).position

或者您可以将其包装到 Item 模型的实例方法中:

def position_in_first_catalogue
  self.catalog_items.find_by_catalogue_id(self.catalogs.first.id).position
end

然后就这样称呼它:

@item.position_in_first_catalogue
于 2009-01-09T14:29:59.927 回答
0

只是添加答案,以便它可以帮助其他人

CatalogItem.joins(:item, :catalog).
  where(items: { id: 4 }).pluck(:position).first
于 2018-04-03T11:28:38.287 回答
-1

如果您提供关联的另一端,您应该能够执行 @catalog.catalog_item.position。

class Catalog < ActiveRecord::Base
  belongs_to :catalog_item
end

现在你可以做 Catalog.first.catalog_item.position。

于 2009-01-09T19:00:42.813 回答
-2

你为什么不只是

@item = Item.find(4)
position = @item.catalog_items.first.position

你为什么要浏览目录?这对我来说没有任何意义,因为您正在寻找第一个 ANY 目录!?

于 2009-01-10T15:19:43.523 回答