I was basing my bug report on my understanding that setting
self.abstract_class = true meant that your model did not have a table
backing it. This has been my experience when using the odbc adapter for
AR against SQL Server, where I have created several abstract models and
instantiated them successfully without having backing tables for them.
However, the traq report says that self.abstract_class = true “means you
can inherit from it (the model) without using STI.”
The RoR API says: “Returns whether this class is a base AR class. If A
is a base class and B descends from A, then B.base_class will return B.”
Q1) Can someone please summarize what the purpose of setting
self.abstract_class is?
Q2) If self.abstract_class = true is NOT meant to create an ActiveRecord
model that is not backed by a table, then what is the correct way to
accomplish that?
Neither of those statements above addresses whether or not the
abstract_class is expected to have a backing table or not. To me, it’s
implied that there is not a backing table (I don’t see how you could
even take advantage of one if there were a backing table).
It makes sense that perhaps it is not expected that an abstract AR class
would even be instantiated so handling issues with around the existence
of a backing table wouldn’t be addressed.
Q2) If self.abstract_class = true is NOT meant to create an ActiveRecord
model that is not backed by a table, then what is the correct way to
accomplish that?
I’m a bit flummoxed by why you’d want an ActiveRecord object that
didn’t have a database table behind it. What would it do? The whole
point of ActiveRecord is to map the object to the database.
If you just want a class that isn’t saved to the database, you can
create a normal Ruby class like
class Person
end
and put it in your /app/models directory and use it.
Q1) Can someone please summarize what the purpose of setting
self.abstract_class is?
Basically, I wanted to provide a class that one of your models could
inherit from with all the functionality. The problem was that Rails was
assuming I wanted to do STI when I just wanted basic ruby inheritance.
Setting abstract class in this case meant there was no table and it only
exists as a class to inherit from and provides no functionality in and
of itself.
This is a longer version of what the reply in that ticket says. It’s
absolutely right. Abstract AR classes aren’t used idrectly, just
inherited from.
Q2) If self.abstract_class = true is NOT meant to create an ActiveRecord
model that is not backed by a table, then what is the correct way to
accomplish that?
If you want an ActiveRecord object without a DB table, then you don’t
want an ActiveRecord object. The entire core functionality of AR is
built around providing an interface to a database table.
If you want a class to validate other AR objects, abstract class will
work for you.
class Foo < ActiveRecord::Base
self.abstract_class = true
validates_presence_of :bar
end
So if I can actually create an instance of an AR object that has
self.abstract_class set to true, then that should be a bug, correct?
I am able to create instances of abstract AR classes when using the ODBC
driver against SQL Server. Should I log that as a bug?
I still would like to be able to get the AR::Validations functionality
for an arbitrary class - I’ll play with seeing if I can just include it
into a regular class.
instantiated them successfully without having backing tables for them.
Q2) If self.abstract_class = true is NOT meant to create an ActiveRecord
model that is not backed by a table, then what is the correct way to
accomplish that?
read my response to the ticket:
An abstract model means you can inherit from it without using STI.
class SuperModel < AR::Base
self.abstract_class = true
end
class Foo < SuperModel
end
Foo.table_name
=> ‘foos’
It’s used in the CachedModel plugin. I’m not sure why it’s a class
and not a mixin though, but ok.
The second is directly including ActiveRecord::Validations into your
class. You may have to implement some of the ActiveRecord API for
this though. I’m pretty sure the wiki has some info on this.
Which now makes me realize that the original behavior I see against SQL
Server is the bug. Do you think that’s a bug?
As Rick said, setting self.abstract_class = true means you can extend
a class without STI kicking in. The class isn’t really abstract in
the strict sense; it can still be instantiated (whichever database
adapter is used). Perhaps base_class or some other signifier
(acts_as_base_class?) would have been less confusing.
I get it now. However, my original issue has to do with what I now
believe to be a bug in the AR ODBC module.
Using AR w/ODBC against SQL Server, I can successfully instantiate a
class with self.abstract_class set to true with no problems. I
convinced myself that part of the intended functionality of
self.abstract_class was to allow the user to take advantage of AR
validations without requiring them to persist the data.
Now I see that that was an incorrect understanding.
Which now makes me realize that the original behavior I see against SQL
Server is the bug. Do you think that’s a bug?
The second is directly including ActiveRecord::Validations into your
class. You may have to implement some of the ActiveRecord API for
this though. I’m pretty sure the wiki has some info on this.