2

Say I have these classes:

class Zoo < ActiveRecord::Base
  has_many :animals
end

class Animal < ActiveRecord::Base;
  belongs_to :zoo
end

class Lion < Animal; end
class Tiger < Animal; end

I can easily do a_zoo.animals but moreover a_zoo.animals << a_lion_or_a_tiger.

What I want to do is directly enable the lions and tigers method for a zoo.

I can easily do the retrieving:

def lions
  animals.where(type: 'Lion')
end
# analogous for the tiger, can be generalized with metaprogramming
# but right now there's no need to

but I'm having a hard time with the modifications. That is, a_zoo.lions returns an AssociationRelation while a_zoo.animals returns a CollectionProxy, which is updatable as far as I'm getting this.

What can I do to have all the functionality of a_zoo.animals transferred to a_zoo.lions and a_zoo.tigers?

whatyouhide
  • 15,897
  • 9
  • 57
  • 71

1 Answers1

-1

You are looking for has_many :lions, through :animals, take a look at http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

Also, given that Animal can be of different types you should check out polymorphic associations.

Mike Szyndel
  • 10,461
  • 10
  • 47
  • 63
  • Is that a solution? I knew of `has_many :through`, but I wasn't using it since I didn't think it could be applied to **generalizations**. – whatyouhide Apr 23 '14 at 22:27
  • I am not sure what you mean by generalizations but that's how I handle similar cases. – Mike Szyndel Apr 23 '14 at 22:29
  • A generalization is practically a superclass. `Animal` is a generalization of `Lion`, which is a **specialization** of an `Animal` itself. I'm not sure adding a `has_many :through` association is the way to go when an association with the parent model is already there. – whatyouhide Apr 23 '14 at 23:08