我有一个Rails 3 ActiveRecord属于两个不同的ActiveRecords。实施例
class Animal < ActiveRecord::Base
belongs_to: species
belongs_to: zoo
...
end
其中animals表包含species_id,zoo_id,name和description以及具有scientific_name和zoo的表种类具有地址。
在控制器中,我有一个查询
@animals = Animal.includes(:species, :zoo).order(:name)
以及我希望在视图中显示的列列表
@columns = ["name", "description", "species.scientific_name", "zoo.address"]
在视图中,我希望创建一个由列名列表驱动的HTML表,例如
<table>
<tbody>
<tr>
<% @animals.each do |animal| %>
<% %columns.each do |col| } %>
<td><%= animal[</td>
<% end %>
<% end %>
</tr>
</tbody>
</table>
这适用于动物的名称和描述,但不适用于species.scientific_name和zoo.address。
我知道我可以特殊情况下循环并直接访问包含的类,如animal.species ['scientific_name'],但我希望有一种方法可以按名称访问包含的类。类似动物['species'] ['scientific_name']
答案 0 :(得分:2)
方法1
Monkey修补ActiveRecord类。有关猴子修补AR类的详细信息,请参阅此answer。
class ActiveRecord::Base
def read_nested(attrs)
attrs.split(".").reduce(self, &:send)
end
end
示例嵌套属性访问:
animal.read_nested("zoos.address")
user.read_nested("contacts.first.credit_cards.first.name")
product.read_nested("industry.category.name")
对于您的用例:
控制器:
@columns = %w(name color zoo.address species.scientific_name)
查看
<% @animals.each do |animal| %>
<% @columns.each do |col| } %>
<td><%= animal.read_nested(col)%></td>
<% end %>
<% end %>
方法2
添加select
子句以选择列并为其设置别名。
@animals = Animal.includes(:species, :zoo).select("
animals.*,
species.scientific_name AS scientific_name,
zoos.address AS zoo_address").
order(:name)
现在,在您看来,您可以像常规模型属性一样访问scientific_name
,zoo_address
等属性。