2009-11-24 41 views
1

可以說我有一個葡萄酒和啤酒模型/控制器,以及具有許多關係的wine_review和beer_review模型。爲兩個具有類似數據類型的模型乾涸代碼

每個表都有幾乎相同的數據類型,例如wine_review和beer_review都有一個評級和評論欄。 酒和啤酒每個都有名字。

我該如何幹起我的代碼,以便他們可以共享相同的視圖。

現在我有兩個意見做同樣的事情,一次用於啤酒,一次用於葡萄酒。

<% @wine_reviews.each do |review| -%> 
    <ul> 
    <li><%= link_to review.wine.name, review.wine %></li> 
    <li><%= review.rating %></li> 
    <li><%=h review.comment %></li> 
    </ul> 
<% end -%> 

<% @beer_reviews.each do |review| -%> 
    <ul> 
    .... 
    .... 

我真的很想做的是一樣的東西

<li><%= link_to review.beverage.name, review.beverage %></li> 

當飲料將與這取決於我的渲染當時葡萄酒或啤酒來代替,但我想不出怎麼做。

因爲review.beverge會中斷,所以我無法將飲料作爲局部傳遞給偏食。

謝謝。

回答

6

你這裏有幾種不同的選擇:

鴨子類型:

在Ruby中,只要一個對象響應的方法調用具有的工作,方法調用。因此,如果啤酒和葡萄酒都有一個屬性:名稱,那麼調用@ result.name可以與任一模型一起使用。

多態關聯:

代替具有review.beer或review.wine的。通過多態關聯使葡萄酒和啤酒可以被審查。這也可以用於評論,例如,兩者都可以評論。請查看acts_as_commentable以瞭解其工作原理。 Railscasts在這個工作方式上有一個excellent screencast

單表繼承:

您可以創建一個對象調用飲料從葡萄酒和啤酒繼承。這允許一個地方放置類似的屬性,並仍然允許有小的差異。

從您的描述來看,您正在尋找所有三種可能的組合。

+0

我認爲用多形性關聯來處理這將是這裏的首選。 – Ben 2009-11-24 19:52:24

+0

立即檢出railscast。看起來這正是我要找的。多謝你們。 – KJF 2009-11-24 19:57:35

1

假設評論沒有葡萄酒和啤酒的評論,您可以嘗試將其添加到您的評論模型。這可能並不是確切的代碼,但重要的是,在你的模型中,你可以找出它是什麼類型的評論,你的觀點不關心。

def beverage 
    @beverage ||= self.beer || self.wine 
end 
1

多態協會是答案。你可以設計你的表包含與檢討:

create_table :beverage_reviews, :force => true do |t| 
    t.string :review_text 
    t.integer :rating 
    t.string :beverage_type 
    t.string :beverage_id 
end 

而且BeverageReview模式可以是:

class BeverageReview < ActiveRecord::Base 
    belongs_to :beverage, :polymorphic => true 
end 

而且BeerWine模式可以是:

class Beer < ActiveRecord::Base 
    has_one :beverage_review, :as => :beverage 
end 

這樣,如果您將顯示所有評論,您可能會將您的代碼編寫爲:

<% @all_reviews.each do |review| -%> 
    <%= review.review_text -%> 
    <%= review.beverage.name -%> 
<% end -%> 
相關問題