2011-10-17 29 views
0

我有一個Rails 3 ActiveRecord屬於兩個不同的ActiveRecords。實施例如何訪問ActiveRecord包含編程

class Animal < ActiveRecord::Base 
    belongs_to: species 
    belongs_to: zoo 
... 
end 

其中動物表包含species_id,zoo_id,名稱和描述以及表物種與scientific_name和動物園具有地址。

在控制器中,我有一個查詢

@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'],但我希望有一種方法可以通過名稱訪問包含的類。類似動物[ '物種'] [ 'scientific_name']

回答

2

方法1

猴修補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_namezoo_address像普通的模型屬性訪問屬性。

+0

不完全像我所希望的那樣靈活。相反,我對一些關鍵列進行了歸一化處理。 –

+0

@SteveWilhelm我添加了一個通用的方法。看一看。 –