I''m struggling with the following problem: I have a class, call it ''School''. An instance of School can have all sorts of assets, such as ''Books'', ''Tables'', ''Chairs'', ''Teachers''. Each of these asset types is modeled by it''s own model and has a corresponding table in the db. So, there is a table for ''Chair, another for ''Teacher'' and so on. In summary, in the abstract, each school has_many assets and each asset belongs_to a school. I''d like to be able to do things like: school = School.find(3) school.assets << Chair.new(chair_params) school.assets << Teacher.new(teacher_params) school.assets.each{|a| puts a.name} I tried to solve it by defining an abstract class: class Asset << ActiveRecord::Base self.abstract_class = true end and inheriting from it: class Book << Assets belongs_to :school end and class School << ActiveRecord::Base has_many :assets end That gets me part way there but I fear is fundamentally flawed. Most of the time it results in complaints from raisl that the table ''Assets'' doesn''t exist, which is true... Any suggestions on how to model the relationship I described would be much appreciated! Yoram -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On 3 March 2011 21:10, Yoram <yorambernet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I''m struggling with the following problem: > > I have a class, call it ''School''. > An instance of School can have all sorts of assets, such as ''Books'', > ''Tables'', ''Chairs'', ''Teachers''. > Each of these asset types is modeled by it''s own model and has a > corresponding table in the db. So, there is a table for ''Chair, > another for ''Teacher'' and so on. > In summary, in the abstract, each school has_many assets and each > asset belongs_to a school.Have you looked at Single Table Inheritance? Colin -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
I''m staying away from STI because I want to be able to add additional asset types over time, none of which share attributes with other assets. So - with STI, I could end up with a table that has hundreds of columns. On Mar 3, 1:13 pm, Colin Law <clan...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> On 3 March 2011 21:10, Yoram <yoramber...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > I''m struggling with the following problem: > > > I have a class, call it ''School''. > > An instance of School can have all sorts of assets, such as ''Books'', > > ''Tables'', ''Chairs'', ''Teachers''. > > Each of these asset types is modeled by it''s own model and has a > > corresponding table in the db. So, there is a table for ''Chair, > > another for ''Teacher'' and so on. > > In summary, in the abstract, each school has_many assets and each > > asset belongs_to a school. > > Have you looked at Single Table Inheritance? > > Colin-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Seems like this is just a reverse of a normal polymorphic association. A tricky problem to solve, since rails doesn''t seem to be designed to handle it. When you call "school_instance.assets" the underlying query would essentially need to be "give me everything from the books table, teachers table, and chairs table". That''s basically impossible if you understand the SQL behind it, since each of these tables has a different schema. Single Table Inheritance solves that issue. It is possible to work around it if you want 3 separate tables... If an asset can belong to only one school, it''s probably easiest to do away with the abstract parent class and just have them each "belong_to :school" Then in your School class, you can add a method to retrieve all the associated assets: class School has_many :teachers has_many :books has_many :chairs def assets self.teachers + self.books + self.chairs end end To add an asset, you''ll have to call the specific "teachers <<" "books <<" or "chairs <<" However, you could also add a method to handle that as well: def add_asset(item) self.books << item if item.is_a?(Book) self.chairs << item if item.is_a?(Chair) self.teachers << item if item.is_a?(Teacher) end -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Mar 3, 4:42 pm, Yoram <yoramber...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I''m staying away from STI because I want to be able to add additional > asset types over time, none of which share attributes with other > assets. So - with STI, I could end up with a table that has hundreds > of columns.And this is a problem because...? Sounds an awful lot like premature optimization. This sort of thing is not supported well by Rails, as it''s tricky to handle in general (after all, one could create additional subclasses of Asset on-the-fly so Rails can''t be sure which tables it should be querying) and even if possible wouldn''t support some operations cleanly - imagine trying to paginate the assets association... One thought was using a join model with a polymorphic belongs_to and has_many :through, but that won''t work either: http://stackoverflow.com/questions/1683265/activerecord-has-many-through-and-polymorphic-associations One thing that *might* work would be to have a model that holds the common attributes that then belongs_to the specific types. Not optimal, but might work with some usage patterns. I''m assuming the models you''re using are generic examples and not the real models, so I''ll skip addressing the fact that there are very few operations / actions that make sense applied to both ''Chair'' and ''Teacher''. Even including both in a single list would seem pretty peculiar. --Matt Jones -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
It depends what you''re going to do with it... Do you know? Blog: http://random8.zenunit.com/ Twitter: http://twitter.com/random8r Learn http://sensei.zenunit.com/ New video up now at http://sensei.zenunit.com/ real fastcgi rails deploy process! Check it out now! On 05/03/2011, at 3:29 AM, Matt Jones <al2o3cr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > On Mar 3, 4:42 pm, Yoram <yoramber...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> I''m staying away from STI because I want to be able to add additional >> asset types over time, none of which share attributes with other >> assets. So - with STI, I could end up with a table that has hundreds >> of columns. > > And this is a problem because...? Sounds an awful lot like premature > optimization. > > This sort of thing is not supported well by Rails, as it''s tricky to > handle in general (after all, one could create additional subclasses > of Asset on-the-fly so Rails can''t be sure which tables it should be > querying) and even if possible wouldn''t support some operations > cleanly - imagine trying to paginate the assets association... > > One thought was using a join model with a polymorphic belongs_to and > has_many :through, but that won''t work either: > > http://stackoverflow.com/questions/1683265/activerecord-has-many-through-and-polymorphic-associations > > One thing that *might* work would be to have a model that holds the > common attributes that then belongs_to the specific types. Not > optimal, but might work with some usage patterns. > > I''m assuming the models you''re using are generic examples and not the > real models, so I''ll skip addressing the fact that there are very few > operations / actions that make sense applied to both ''Chair'' and > ''Teacher''. Even including both in a single list would seem pretty > peculiar. > > --Matt Jones > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Thanks all... I ended up solving this much along the lines that Tim recommended - lots of ''has_many'' statements in the School model and several custom built accessors such as those that Tim described. I appreciate the help. Yoram On Mar 4, 9:29 am, Matt Jones <al2o...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Mar 3, 4:42 pm, Yoram <yoramber...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > I''m staying away from STI because I want to be able to add additional > > asset types over time, none of which share attributes with other > > assets. So - with STI, I could end up with a table that has hundreds > > of columns. > > And this is a problem because...? Sounds an awful lot like premature > optimization. > > This sort of thing is not supported well by Rails, as it''s tricky to > handle in general (after all, one could create additional subclasses > of Asset on-the-fly so Rails can''t be sure which tables it should be > querying) and even if possible wouldn''t support some operations > cleanly - imagine trying to paginate the assets association... > > One thought was using a join model with a polymorphic belongs_to and > has_many :through, but that won''t work either: > > http://stackoverflow.com/questions/1683265/activerecord-has-many-thro... > > One thing that *might* work would be to have a model that holds the > common attributes that then belongs_to the specific types. Not > optimal, but might work with some usage patterns. > > I''m assuming the models you''re using are generic examples and not the > real models, so I''ll skip addressing the fact that there are very few > operations / actions that make sense applied to both ''Chair'' and > ''Teacher''. Even including both in a single list would seem pretty > peculiar. > > --Matt Jones-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.