「id」と「language」の2つの列に基づいてレコードの一意のキーを定義したい
ユーザーが次の文字列を送信できるようにするには: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
この
class Language < ActiveRecord::Base
has_many :words
attr_accessible :lang
end
add_index :words, ["id", "language_id"], :unique => true
動作するはずです。データベースにすでに一意でないデータがいくつかあり、インデックスを作成できない場合がありますか?しかし(IDは常に一意であるため、@ Doonが冗長であることに気づいたように)。したがって、2つの列に主キーを作成する必要があります。
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);"
そして、このgemを使用してモデルにprimary_keyを設定します。 http://rubygems.org/gems/composite_primary_keys :
class Word < ActiveRecord::Base
self.primary_keys = :id,:language_id
end
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
Word
モデルにprimary_key
属性を設定する必要もありません。
私のコメントで述べたように、あなたはRailsと戦うことになり、箱から出して実際にサポートされていません。あなたは http:// compositekeys .rubyforge.org Railsで複合主キーを実行する方法を提供します。まだ必要がなかったので、使用していません(通常、複合キーのようなものがある場合)主キーと結合されたペアの一意のインデックス(HABTM)のない結合テーブル。
モデル
class User < ActiveRecord::Base
has_secure_password
self.primary_keys = :name
end
移行
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name, null: false
t.string :emailid
t.string :password_digest
t.integer :locked, :default => 0
t.text :secretquestion
t.string :answer
t.timestamps null: false
end
add_index :users, :name, :unique => true
end
end
このテーブルを取得します
@ rogal111が言ったように、主キーが既に存在する場合は、これを実行する必要があります。
ALTER TABLE sections DROP PRIMARY KEY, ADD PRIMARY KEY(id, workspace_id, section_key);
ユースケースに応じて、 composite key gem を試してみることができます。これにより、複合主キーを定義し、ActiveRecordがこの種のモデルを処理できるようになります(このモデルへの関連付けに役立ちます。 url_forヘルパーなど)。
したがって、このモデルを他のRailsモデルとして使用することを計画している場合、gemは大いに役立ちます。
サイトをRailsに移行するときに、同様の問題に直面しました。サイトが利用可能な各言語のテキストデータを格納するテーブルがあるため、次のようなものがありました。
CREATE TABLE Project_Lang(
project_id INT NOT NULL,
language_id INT NOT NULL,
title VARCHAR(80),
description TEXT,
PRIMARY KEY pk_Project_Lang(project_id, language_id),
FOREIGN KEY fk_Project_Lang_Project(project_id)
REFERENCES Project(project_id)
ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY fk_Project_Lang_Language(language_id)
REFERENCES Language(language_id)
ON DELETE RESTRICT ON UPDATE CASCADE
)ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_spanish_ci;
しかし、Railsはすぐに使用できる複合主キーを処理しないため、テーブルの構造を変更して、それが独自の主キーを持つようにしました。
CREATE TABLE Project_Lang(
project_lang_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
project_id INT NOT NULL,
language_id INT NOT NULL,
title VARCHAR(80),
description TEXT,
UNIQUE INDEX(project_id, language_id),
FOREIGN KEY fk_Project_Lang_Project(project_id)
REFERENCES Project(project_id)
ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY fk_Project_Lang_Language(language_id)
REFERENCES Language(language_id)
ON DELETE RESTRICT ON UPDATE CASCADE
)ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_spanish_ci;
また、重複レコードが挿入されないように、以前に複合主キーを作成した列に一意のインデックスを作成しました。それから私のRailsモデルで私は簡単にできました:
self.primary_key = "project_lang_id"
そして、それはトリックをしました。私が望んだものではありませんが、フレームワークと戦うよりはましです。