Another question about single table inheritance.
I created PostType migration as follows:
class CreatePostTypes < ActiveRecord::Migration
def self.up
create_table :post_types do |t|
attributes for all post types
t.column :type, :string
t.column :ptypename, :string
parent post_type_id
t.column :parent_id, :integer
end
end
def self.down
drop_table :post_types
end
end
I created PostType model as follows:
class PostType < ActiveRecord::Base
end
class MainType < PostType
end
class SubType < MainType
belongs_to :parent_type, :class_name => ‘SubType’, :foreign_key =>
:parent_id
end
when I tried doing:
MainType.new(:ptypename=>‘MAIN’) or MainType.create(:ptypename=>‘MAIN’)
I got error
NameError: uninitialized constant MainType
How can I fix it? thanks.
On 2/23/07, new rails user [email protected] wrote:
class SubType < MainType
belongs_to :parent_type, :class_name => ‘SubType’, :foreign_key =>
:parent_id
end
Ok, my initial question is: are you trying to do one level categorization
such as:
Parent Type
|
|
Sub Sub
Or are you trying to do
Parent Type
|
|
---------------------
Sub Sub
| |
------------- --------------
Sub Sub Sub Sub
etc etc… multiple levels of types.
On 2/23/07, new rails user [email protected] wrote:
Thanks.
class PostType < ActiveRecord::Base
belongs_to :parent, :class_name => ‘PostType’, foreign_key =>
‘parent_id’
has_many :sub_post_types, :class_name => ‘PostType’
end
p = PostType.new
p.save
subp = PostType.new
subp.parent = p
subp.save
subp2 = PostType.new
subp2.parent = p
subp2.save
p.sub_post_types will return [subp, subp2]
subp.parent will return p
subp2.parent will return p
And in your migration you would need
create_table :post_types do |t|
t.column :parent_id, :int
t.column :type_name, :string
end
This sets it up, actually, the second way I mentioned, but you can just
use
it as the first if you want.
Any given PostType will have a parent as post_type.parent and any given
PostType can have as many children as it wants, accessible via
post_type.sub_post_types
Is this what you need?
I tried your codes today. every thing seems ok.
sub.parent works. however it does not work after I run p.sub_post_types
and get error. The error message is
ERROR: column post_types.post_type_id does not exist
LINE 1: SELECT * FROM post_types WHERE (post_types.post_type_id = 23…
^
It seems it is looking for a column named post_type_id that does not
exist. why?
Could you please give me more hints? thanks.
Luke I. wrote:
On 2/23/07, new rails user [email protected] wrote:
This sets it up, actually, the second way I mentioned, but you can just
use
it as the first if you want.
Any given PostType will have a parent as post_type.parent and any given
PostType can have as many children as it wants, accessible via
post_type.sub_post_types
Is this what you need?
Luke I. wrote:
On 2/24/07, new rails user [email protected] wrote:
It seems it is looking for a column named post_type_id that does not
exist. why?
Could you please give me more hints? thanks.
I’m sorry, I forgot a very important part (shows what I get for not
testing
my code before I gave it to you)
The line
has_many :sub_post_types, :class_name => ‘PostType’
should instead be
has_many :sub_post_types, :class_name => ‘PostType’, :foreign_key =>
‘parent_id’
That should fix it.
This time it is working. Thanks so much.
I never though I may put :foreign_key to has_many.
On 2/24/07, new rails user [email protected] wrote:
It seems it is looking for a column named post_type_id that does not
exist. why?
Could you please give me more hints? thanks.
I’m sorry, I forgot a very important part (shows what I get for not
testing
my code before I gave it to you)
The line
has_many :sub_post_types, :class_name => ‘PostType’
should instead be
has_many :sub_post_types, :class_name => ‘PostType’, :foreign_key =>
‘parent_id’
That should fix it.
Luke I. wrote:
Yeah… what it’s doing (in case you’re curious):
When you tell the belongs_to line that it’s foreign_key is parent_id,
that
means that when you set a parent, it sets parent_id to the id of the
parent.
Then, when you call something like (p.sub_post_types), what it’s
generating
behind the scenes is SELECT * from post_types where
post_types.sub_post_type_id = #{self.id}
In order to change that query to use post_types.parent_id instead of
post_types.sub_post_type_id, you set the foreign key.
the way you do is removing type column. each time when one type looks
for its parent or sub_post_types, just use
@post_type.parent or @post_type.sub_post_types
right?
If I understand what you’re asking, then: right!
Yeah… what it’s doing (in case you’re curious):
When you tell the belongs_to line that it’s foreign_key is parent_id,
that
means that when you set a parent, it sets parent_id to the id of the
parent.
Then, when you call something like (p.sub_post_types), what it’s
generating
behind the scenes is SELECT * from post_types where
post_types.sub_post_type_id = #{self.id}
In order to change that query to use post_types.parent_id instead of
post_types.sub_post_type_id, you set the foreign key.