Modules vs. Classes and their influence on descendants of ActiveRecord::Base

Posted by Chris on Stack Overflow See other posts from Stack Overflow or by Chris
Published on 2010-02-22T19:57:02Z Indexed on 2010/05/23 5:10 UTC
Read the original article Hit count: 215

Here's a Ruby OO head scratcher for ya, brought about by this Rails scenario:

class Product < ActiveRecord::Base
  has_many(:prices)
  # define private helper methods 
end

module PrintProduct
  attr_accessor(:isbn)
  # override methods in ActiveRecord::Base
end

class Book < Product
  include PrintProduct
end

Product is the base class of all products. Books are kept in the products table via STI. The PrintProduct module brings some common behavior and state to descendants of Product. Book is used inside fields_for blocks in views. This works for me, but I found some odd behavior:

  • After form submission, inside my controller, if I call a method on a book that is defined in PrintProduct, and that method calls a helper method defined in Product, which in turn calls the prices method defined by has_many, I'll get an error complaining that Book#prices is not found.

Why is that? Book is a direct descendant of Product!

More interesting is the following..

As I developed this hierarchy PrintProduct started to become more of an abstract ActiveRecord::Base, so I thought it prudent to redefine everything as such:

class Product < ActiveRecord::Base
end

class PrintProduct < Product
end

class Book < PrintProduct
end

All method definitions, etc. are the same. In this case, however, my web form won't load because the attributes defined by attr_accessor (which are "virtual attributes" referenced by the form but not persisted in the DB) aren't found. I'll get an error saying that there is no method Book#isbn. Why is that?? I can't see a reason why the attr_accessor attributes are not found inside my form's fields_for block when PrintProduct is a class, but they are found when PrintProduct is a Module.

Any insight would be appreciated. I'm dying to know why these errors are occurring!

© Stack Overflow or respective owner

Related posts about ruby-on-rails

Related posts about ruby