优雅地从has_many中选择属性:通过Rails中的连接模型
我想知道在has_many中通过连接模型选择属性的最简单/最优雅的方法是:通过关联。
假设我们有Items,Catalogs和CatalogItems,它们包含以下Item类:
class Item :catalog_items end
另外,假设CatalogueItems有一个position属性,并且在任何目录和任何项目之间只有一个CatalogueItem。
检索position属性最明显但又有点令人沮丧的方法是:
@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 :catalog_items, :select => "catalogue_items.position, catalogs.*" end
现在我可以做Item.catalogs.first.position。 但是,这看起来有点像黑客 – 我在Catalog实例上添加了一个额外的属性。 它还开辟了在两种不同情况下尝试使用视图的可能性,其中我使用Catalog.find或@ item.catalogs填充@catalogs。 在一种情况下,位置将在那里,而在另一种情况下,它不会。
有人有一个很好的解决方案吗?
谢谢。
你可以这样做:
# 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
只需添加答案,以便它可以帮助其他人
CatalogItem.joins(:item, :catalog). where(items: { id: 4 }).pluck(:position).first
如果您提供关联的另一端,您应该能够执行@ catalog.catalog_item.position。
class Catalog < ActiveRecord::Base belongs_to :catalog_item end
现在你可以做Catalog.first.catalog_item.position。
你为什么不这样做
@item = Item.find(4) position = @item.catalog_items.first.position
你为什么要浏览目录? 这对我来说没有任何意义,因为你正在寻找第一个目录!?