Дайте составной первичный ключ в Rails - PullRequest
2 голосов
/ 22 февраля 2011

Как мне дать составной первичный ключ в Rails без каких-либо драгоценных камней?

Моя первая таблица в файле миграции:

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string :userid
      t.string :name
      t.string :address
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end

Моя вторая таблица в файле миграции:

class CreateProjects < ActiveRecord::Migration
  def self.up
    create_table :projects do |t|
      t.string :title
      t.string :description
      t.timestamps
    end
  end
  def self.down
    drop_table :projects
  end
end

В моем файле схемы:

ActiveRecord::Schema.define(:version => 20110222044146) do
  create_table "projects", :force => true do |t|
    t.string   "title"
    t.string   "description"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "users", :force => true do |t|
    t.string   "userid"
    t.string   "name"
    t.string   "address"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
end

Теперь я хочу создать таблицу с именем User_has_project, в которой я буду ссылаться на пользователя и проектэто означает, что будет иметь 2 внешних ключа.Итак, я попробовал так:

class CreateUser_has_projects < ActiveRecord::Migration
  def self.up
    create_table :user_has_projects do |t|
      t.references :User
      t.references :Project
      t.boolean :status
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end

Теперь, как я могу установить комбинацию user_id и project_id в качестве первичного ключа в user_has_projects?

1 Ответ

2 голосов
/ 22 февраля 2011

Похоже, вы пытаетесь указать отношение "многие-многие" между Users и Projects, с дополнительным полем в самой связи.

То, что вы делаете в настоящее время, не является способом работы Rails, особенно с концепцией составного первичного ключа.

Способ Rails / ActiveRecord для такого рода моделирования отношений заключается в наличии третьей модели, которая описывает отношения между User и Project. Для примера, я собираюсь назвать это Assignment. Все, что вам нужно сделать, это переименовать таблицу user_has_projects в assignments следующим образом:

class CreateAssignments < ActiveRecord::Migration
  def self.up
    create_table :assignments do |t|
      t.references :user
      t.references :project
      t.boolean :status
      t.timestamps
    end
  end

  def self.down
    drop_table :assignments
  end
end

А потом, в файлах вашей модели:

# app/models/user.rb
class User < ActiveRecord::Base
  has_many :assignments
  has_many :projects, :through => :assignments
end

# app/models/assignment.rb
class Assignment < ActiveRecord::Base
  belongs_to :user
  belongs_to :project
end

# app/models/project.rb
class Project < ActiveRecord::Base
  has_many :assignments
  has_many :users, :through => :assignments
end

Подробнее об этом можно прочитать здесь: http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association

...