为两个具有类似数据类型的模型干涸代码
可以说我有一个葡萄酒和啤酒模型/控制器,以及具有许多关系的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会中断,所以我无法将饮料作为局部传递给偏食。
谢谢。
你这里有几种不同的选择:
鸭子类型:
在Ruby中,只要一个对象响应的方法调用具有的工作,方法调用。因此,如果啤酒和葡萄酒都有一个属性:名称,那么调用@ result.name可以与任一模型一起使用。
多态关联:
代替具有review.beer或review.wine的。通过多态关联使葡萄酒和啤酒可以被审查。这也可以用于评论,例如,两者都可以评论。请查看acts_as_commentable以了解其工作原理。 Railscasts在这个工作方式上有一个excellent screencast。
单表继承:
您可以创建一个对象调用饮料从葡萄酒和啤酒继承。这允许一个地方放置类似的属性,并仍然允许有小的差异。
从您的描述来看,您正在寻找所有三种可能的组合。
假设评论没有葡萄酒和啤酒的评论,您可以尝试将其添加到您的评论模型。这可能并不是确切的代码,但重要的是,在你的模型中,你可以找出它是什么类型的评论,你的观点不关心。
def beverage
@beverage ||= self.beer || self.wine
end
多态协会是答案。你可以设计你的表包含与检讨:
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
而且Beer
和Wine
模式可以是:
class Beer < ActiveRecord::Base
has_one :beverage_review, :as => :beverage
end
这样,如果您将显示所有评论,您可能会将您的代码编写为:
<% @all_reviews.each do |review| -%>
<%= review.review_text -%>
<%= review.beverage.name -%>
<% end -%>
我认为用多形性关联来处理这将是这里的首选。 – Ben 2009-11-24 19:52:24
立即检出railscast。看起来这正是我要找的。多谢你们。 – KJF 2009-11-24 19:57:35