根据2列定义唯一主键

Sté*_*e V 35 ruby-on-rails primary-key composite-primary-key

我想根据2列定义记录的唯一键:'id'和'language'

让用户提交以下字符串:id = 1 language = en value = blabla english id = 1 language = fr value = blabla french

我尝试使用set_primary_key和add_index,但它不起作用(add_index:words,["id","language_id"],:unique => true)

我有以下型号:

class Word < ActiveRecord::Base
  belongs_to :dictionnary
  belongs_to :language

  attr_accessible :lang, :rev, :value, :dictionnary_id, :language_id

  validates :value, :uniqueness => true

end  
Run Code Online (Sandbox Code Playgroud)

还有这个

class Language < ActiveRecord::Base
    has_many :words

    attr_accessible :lang
end
Run Code Online (Sandbox Code Playgroud)

rog*_*111 50

add_index :words, ["id", "language_id"], :unique => true

它应该工作.也许您的数据库中已经存在一些非唯一数据,并且无法创建索引?但是(因为@Doon注意到它将是多余的,因为id总是唯一的).因此,您需要在两列上创建主键.

要在rails中定义2列主键,请使用:

create_table :words, {:id => false} do |t|
  t.integer :id
  t.integer :language_id
  t.string :value
  t.timestamps
end
execute "ALTER TABLE words ADD PRIMARY KEY (id,language_id);"
Run Code Online (Sandbox Code Playgroud)

并使用此gem在您的模型中设置primary_key:http://rubygems.org/gems/composite_primary_keys:

class Word < ActiveRecord::Base
    self.primary_keys = :id,:language_id
end
Run Code Online (Sandbox Code Playgroud)

  • 也可能:`validates:language_id,uniqueness:{scope:[:id]}` (3认同)

Vad*_*dim 6

在Rails 5中,您可以执行以下操作:

create_table :words, primary_key: %i[id language_id] do |t|
  t.integer :id
  t.integer :language_id
  t.string :value
  t.timestamps
end
Run Code Online (Sandbox Code Playgroud)

也没有必要primary_keyWord模型上设置属性.

  • Rails 5 [仍然不支持复合主键](https://github.com/rails/rails/blob/e00b467c479e495292095e09ce53b326035ec467/activerecord/lib/active_record/attribute_methods/primary_key.rb#L131) (5认同)