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: