Auto Generated ID

Will T. wrote:

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.

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 Paul
gustav@rails.co.za

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/
gustav@rails.co.za

Will T. wrote: