Auto Generated ID

Good day everyone,

I am using the db_schema_import in creating tables for my DB. It seems
to me that it automatically generates a column named “ID” for each table
I created. Is there anyway to change this behavior?

Note: Sometimes, I would like to use natural keys instead of the
surrogate ones.

Thank you in advance,

Will T.

Will T. wrote:

Will T.

Hey

create_table ‘items’, :primary_key => ‘surrogate_id’ do |t|

t.column …

end

And in your model I’m pretty sure you need to tell rails not to use
‘id’, but to use ‘surrogate_id’ instead…

I think this is done as follows:

class Item < ActiveRecord::Base
primary_key ‘surrogate_id’

#rest of model
end

There’re consequences though:

ActiveRecord::Base
http://www.railsmanual.org/class/ActiveRecord%3A%3ABase

And more specifically the primary_key() method
http://www.railsmanual.org/class/ActiveRecord%3A%3ABase/primary_key

Hope this helps

Cheery-o
Gustav P.
[email protected]

Paul Gustav,

Thank you for your reply and explanation about the consequences of
defining my own PK. As for right now, I am more familiar with the
natural keys in database modeling than using the auto-generated ones (I
think RoR recommends using this).
I would like to create an application in the “RoR” way and benefit from
it. Where would you suggest to be a good start for me to learn this DB
modeling technique using surrogate keys?

For example: a linking table in the “natural key” design will consist of
2 columns as its PK (each from the table that you are linking). If we
were to use auto-generated ID, how would this look like? (I can’t
picture this in my head).

Thank you,

Will T.

Gustav P. wrote:

Will T. wrote:

Will T.

Hey

create_table ‘items’, :primary_key => ‘surrogate_id’ do |t|

t.column …

end

And in your model I’m pretty sure you need to tell rails not to use
‘id’, but to use ‘surrogate_id’ instead…

I think this is done as follows:

class Item < ActiveRecord::Base
primary_key ‘surrogate_id’

#rest of model
end

There’re consequences though:

ActiveRecord::Base
http://www.railsmanual.org/class/ActiveRecord%3A%3ABase

And more specifically the primary_key() method
http://www.railsmanual.org/class/ActiveRecord%3A%3ABase/primary_key

Hope this helps

Cheery-o
Gustav P.
[email protected]

Hey

First of all, I hope I understand you correctly :]

A linking table in Rails used to be implemented as:

members
id
name

roles
id
title

members_roles (the table names are alphabetically ordered, with no /id
/column necessary since any record is uniquely identified by its value
pair)
member_id
role_id

Then you’d define the relationship in your models as:

class Member < ActiveRecord::Base
has_and_belongs_to_many :roles
end

class Role < ActiveRecord::Base
has_and_belongs_to_many :members
end

With the linking being done transparently…

This allowed you to do things like:
@member = Member.find_first
@member.roles << Role.find_by_title( ‘Administrator’ )

Recently, however, using has_and_belongs_to_many has become somewhat
deprecated. It is now more common (and useful IMHO) to use /has_many
:through/

The /has_many :through /implementation allows virtually the same
functionality, but its more versatile, eg:

members
id
name

roles
id
title

permissions
id
set_by_id
created_on
member_id
role_id

The models then look as follows:

class Permission < ActiveRecord::Base
belongs_to :permitted_by, :class_name => ‘Member’, :foreign_key =>
‘set_by_id’
belongs_to :member
belongs_to :role
end

class Member < ActiveRecord::Base
has_many :permitted, :class_name => ‘Permission’, :foreign_key =>
‘set_by_id’
has_many :permissions
has_many :roles, :through => :permissions
end

class Role < ActiveRecord::Base
has_many :permissions
has_many :members, :through => :permissions
end

This means you can now get all the members that were assigned the
‘Administrator’ role in the past week…
@permissions = Permission.find :all, :conditions => [ ‘roles.title = ?
and created_on > ?’, ‘Administrator’, 1.week.ago ], :include => [:role,
:member]
members_granted_administrative_privelages =
@permissions.collect(&:member)

You can still get a member’s roles:
@member = Member.find_first
@member.roles
#=> Array of Roles

Basically, in a one-to-many relationship, the foreign key in the child
table is the singularized name of the parent table with ‘_id’
appended…the value in the foreign key is the value of the id column in
the parent record.

members
id
name

posts
id
title
body
/member_id/

if you define the relationships in the models, Rails assumes this as the
convention, as such you can say:

class Post < ActiveRecord::Base
belongs_to :member
end

And Rails will assume that the posts table has an integer column named
/member_id/ that refers to the parent record.

So you can say things like:
@post = Post.find_first
@member = @post.member
@member.roles == @post.member.roles

Anyway, I’ve written a lot, probably far more than necessary and I
apologize for any waffle or mistakes :]
I’m not quite sure what your first paragraph means, so you’ll notice I
basically just commented on your second one.

I hope this helps, feel free to mail me directly as well if you’d like.

Cheery-o!

Gustav :slight_smile: yup, my surname’s /Paul/
[email protected]

Gustav P.,

Excellent examples. Thank you for spending your time explaining this
concept to me. This helps me greatly. Again, thank you.

With much appreciation,

Will T.