Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set composite key in Rails application

I am using 'foriegner' gem in my application to set primary key, now i am in a situation to set composite primary key in a table.

I searched the web for this, but could not able to find a clear solution for this.

Please suggest me if its possible to set composite keys in rails application using foreigner gem or by any other means.

Note : I am using Postgres

thanks.

like image 832
balanv Avatar asked Jun 20 '12 07:06

balanv


2 Answers

ActiveRecord

There is a gem called composite_primary_keys and integrates these features quite will for ActiveRecord.

It supports a wide array of ActiveRecord versions.

# Gemfile
gem 'composite_primary_keys', '=<version for your AR version>'

Use it like the following example:

class Membership < ActiveRecord::Base
  self.primary_keys = :user_id, :group_id
end

membership = Membership.find([1,1])  # composite ids returns single instance
# => <Membership:0x39218b0 @attributes={"user_id"=>"1", "group_id"=>"1"}>

I am happily using it in production, keeping my schema clean and tidy.

Better alternative: Sequel

As always, if you are looking for a great Ruby + PostgreSQL solution, look no further than jeremyevans/sequel.

It comes with a vast amount of features, including composite primary keys. Out of the box.

So if you are starting a new project (on PostgreSQL obviously), save yourself the headache of ActiveRecord and go with Sequel.

class Post < Sequel::Model
  set_primary_key [:category, :title]
end
like image 198
Overbryd Avatar answered Sep 28 '22 03:09

Overbryd


Short answer: DON'T use composite PKs in Rails (unless you are forced to do so because of a legacy DB).

While there might be solutions with gems that work (currently) this is just not the way that ActiveRecord works. I'd also not use composite PKs outside of Rails unless there is a really good reason. They make a lot of things more complicated.

But: nothing prevents you from having what you think of a a composite primary key as an alternative key and have the Rails default PK (postgres: pseudotype 'serial' which draws its values from a sequence). Just make sure that you add a unique index for those columns that make up your key.

like image 26
Pascal Avatar answered Sep 28 '22 04:09

Pascal