arj*_*jun 5 ruby ruby-on-rails associations has-many has-many-through
我想知道在has_many中通过连接模型选择属性的最简单/最优雅的方式是:通过关联是什么.
假设我们有Items,Catalogs和CatalogItems,它们包含以下Item类:
class Item < ActiveRecord::Base
has_many :catalog_items
has_many :catalogs, :through => :catalog_items
end
Run Code Online (Sandbox Code Playgroud)
另外,假设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
Run Code Online (Sandbox Code Playgroud)
这很烦人,因为我们似乎应该可以执行@ 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
Run Code Online (Sandbox Code Playgroud)
现在我可以做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
Run Code Online (Sandbox Code Playgroud)
或者您可以将其包装到 Item 模型的实例方法中:
def position_in_first_catalogue
self.catalog_items.find_by_catalogue_id(self.catalogs.first.id).position
end
Run Code Online (Sandbox Code Playgroud)
然后像这样调用它:
@item.position_in_first_catalogue
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4744 次 |
| 最近记录: |