开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜