我是Ruby on Rails的新手,所以我对模型关联知之甚少。但这是我的问题:
我有一个项目资源,“has_many:items”。每个项目都有一个名称和一种(该种类指定了它的项目类型)。我想根据“种类”价值做出不同的联想......就像这样:
class Item < ActiveRecord::Base
belongs_to :project, :dependent => :destroy
has_many :sports, :class_name => 'NormalSport' # if kind = 'normal_sport'
has_many :sports, :class_name => 'SuperSport' # if kind = 'super_sport'
has_many :sheep # if kind = 'sheep'
has_many :drinks # if kind = 'drink'
end
因此,这意味着一个项目可以是“normal_sport”,“super_sport”,“sheep”或“drink”。因此,如果该项目是normal_sport,我希望能够说(类似):
Project.first.items.first.sports.all
然后“体育”进入“NormalSport”课程。
但也许这是错误的做法。我正在寻找多态关联......但它看起来并不像是那种关联。这种关联是什么? “项目”只是某种“中间人模式”?
谢谢! (抱歉我的英语不好)
祝你好运 亚历山大
谢谢你们的回答。但似乎它不喜欢路线。如果我说的话(在item-partial中循环项目的所有项目):
<%= link_to 'Destroy', [@project, item], :confirm => 'Are you sure?', :method => :delete %>
它的行为并不像它想要的那样。如果它是“SuperSport”-item,则使用URL:
/projects/1/super_sport/4
如果它是“羊” - 那么它就会进入
/projects/1/sheep/5
我怎么说,他们都应该去:
/projects/:project_id/items/:item_id
他们都使用ItemsController。如果他们都可以使用这条路线会很好。我尝试了这个黑客:
class Item < ActiveRecord::Base
belongs_to :project
validates_uniqueness_of :type, :scope => :project_id
# Hack.
def self.model_name
name = 'item'
name.instance_eval do
def plural; pluralize; end
def singular; singularize; end
end
return name
end
end
然后验证中断了。我希望你理解我的问题!
答案 0 :(得分:4)
看起来你想要STI,所以有一个基类具有共享功能,但不同类型的模型从中继承。 STI易于实施:
class Sport < ActiveRecord::Base
belongs_to :item
end
class NormalSport < Sport
end
class SuperSport < Sport
end
class Item < ActiveRecord::Base
has_many :sports
has_many :normal_sports
has_many :super_sports
end
通过使用正确的类,Rails将自动为您过滤sports
表。如果使用不同的类很麻烦,您还可以使用基础Sport
类并手动过滤type
字段。
答案 1 :(得分:1)
如果多态关联不能满足您的需求,您还可以查看单表继承(STI)。
另一种方法是定义选择子模型的范围。