Ruby on Rails - has_many based on "kind"
I am new to Ruby on Rails, so I do not know so much about model association. But here is my problem:
I have a project resource, which "has_many :items". Each item have a name and a kind (the kind specifies the type of item it is). I want to make different associations based on the "kind"-value... like this:
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
So, this means an item can be either a "normal_sport", "super_sport", "sheep" or "drink". So if the item is a normal_sport I would like to be able to say (something like):
Project.first.items.first.sports.all
And then the "sports" goes to the "NormalSport" class.
But maybe this is the WRONG way of doing this. I was looking on polymorphic associations... but it doesn't look like it is that kind of association. Which kind of association is this? Where the "Item" is just some kind of "middle-man-model"?
Thanks! (and sorry for my bad English)
Best regards Alexander
Thank you both for the answer. But it seems like it does not like the routes. If I say something like (in the item-partial which loops all the items for a project):
<%= link_to 'Destroy', [@project, item], :confirm => 'Are you sure?', :method => :delete %>
It does not behave as a want it to. If it is a "SuperSport"-item, it uses the URL:
/projects/1/super_sport/4
And if it is a "Sheep"-item, it goes to
/projects/1/sheep/5
How can I say, that they ALL should go to:
/projects/:project_id/items/:item_id
They all use the ItemsController. It would be nice if they all could use this route. I tried with this hack:
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
But then the valida开发者_如何学运维tion breaks. I hope you understand my problem!
It looks like you want STI, so there is a base class with the shared functionality but different types of models that inherit from it. STI is easy to implement:
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
By using the correct class, Rails will automatically filter the sports
table for you. If using different classes are cumbersome, you can also use the base Sport
class and filter on the type
field manually.
If polymorphic associations don't serve your needs you can also look into Single table inheritance (STI).
Another approach would be to define scopes for the selection of child models.
精彩评论