Inheritance problem in model

Hello,

I’ve got a problem with the inheritance as soon as I try to use it in a
model.

I’ve got plenty of items which can share a lot of code, so I created a
class “Item”, which inherits from ActiveRecord::Base, but because it’s
not a “real item” but an interface, I set it abstract (writing
abstract_class? method).
Then I have all the differents items I can use (for instance:
book,picture,…) which have their own class.

I tried to write it down like :

class Item < ActiveRecord::base
def abstract_class?
true
end

#stuff
end

class Book < Item
def abstract_class?
false
end
#stuff
end

The problem is, when I call Book.new.title I get an error saying that
the method doesn’t exist (even if Book table has got a title column),
and if I try Book.find(:first).title, it works…
I’ve got the impression that Book.new returns an Item instead of a Book
… Does anyone know how to fix my problem?
Thanks a lot

You’ve defined abstract_class? as an instance method rather than as a
class method. It’s a little less verbose to just do
class Item < ActiveRecord::Base
self.abstract_class = true
end

Fred

Hi,

I tryed that but the problem is still the same…

What’s the actual code you’ve got, the actual error message you get
and the database structure of the books table ?

Fred

The code :

class Book < Item

has_and_belongs_to_many :collections

validates_presence_of :label
validates_presence_of :description

validates_uniqueness_of :label, :case_sensitive => false

include Element

UPLOAD_DIR=“uploads/”

self.abstract_class=false

#methods
end

class Item < ActiveRecord::Base
attr_reader :product, :quantity

self.abstract_class=true

def initialize
@quantity = 1
end

def increment_quantity
@quantity += 1
end

def real_price
price * @quantity
end
end

The error:

You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.include?

Extracted source (around line #5):

2: <%=debug @element%>
3: <% fieldset_tag ‘Book data’ do %>
4:
5: <%[email protected]_field :label%>

6: <%[email protected]_area :description%>

7: <%[email protected]_field :upload_file%>
8: <%end%>

The error :
#{RAILS_ROOT}/vendor/rails/activerecord/lib/active_record/base.rb:1844:in
`method_missing’

SQL query creating the Book table

CREATE TABLE books (
id int(11) NOT NULL auto_increment,
label varchar(255) default NULL,
description text,
required_credits int(11) default NULL,
url varchar(255) default NULL,
price int(11) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=latin1

If you need any other detail please let me know

thanks a lot

At the moment I don’t have any initialize method … I used the default
constructor… I tried to specify it calling super inside but still got
the same error :confused:

In your initialize you need to call the super class initialize method
(AR::Base’s initialize sets up some important stuff). Also I seem to
recall that there are some issues involved with overriding AR::Base’s
implementation of initialize. At the very least you need to make your
initialize pass through any arguments or block specified to super

Fred

Thanks a lot!

That solved the problem.

Sure you do:

def initialize
@quantity = 1
end

That should probably be

def initialize(*args, &block)
super(*args, &block)
@quantity = 1
end

Or, don’t define initialize at all and use an after_initialize
callback.

Fred