Ruby on Railsで主キーを再定義する

レールは、「構成よりも規約が優先される」(構成より規約)という規則で有名です。 しかし、非常にまれに、いくつかのことを異なる方法で行う必要があります。 これらのケースの1つを記事で共有したいと思います。 テーブルで主キーを作成する方法を説明します(Rails 4.2.0を使用)。 実際、複雑なことは何もありませんが、これを行う方法についての質問は時々尋ねられ、答えは常に良いとは限りません。



辞書を書いていると想像してください。 実際には、1対多、多対多、多対多のすべての種類の関連を持つ単語テーブルに関連付けられた数十のテーブルがあります。 ほとんどのクエリでは、目的のテーブルに加えて、単語列も出力する必要があります。つまり、テーブルを結合する必要があります。 サードパーティのワーカーも大根で大量のテキストを処理しており、ワーカーはリレーショナルデータベースの単語にも識別子があることを知りません。 これはすべて、ほとんど身体的な痛みを引き起こし、時々考えます-多分何か違うことをする価値がありますか? 自由意志により、あなたが決める-単語テーブル内の単語は一意であるため、IDを使って、単語自体を主キーにします。 所属するすべての関係では、もはや結合する必要がなく、ワーカーは識別子を確認する必要がありません。頭痛なく情報を異なるデータベースに分解できます。



たとえば、単語(プライマリフィールドwordを含む)と定義(単語への所属先の関連付け)の2つのテーブルがあるとします。 移行を記述します。



class CreateWords < ActiveRecord::Migration def change create_table :words, id: false do |t| t.string :word, null: false t.timestamps null: false end add_index :words, :word, unique: true end end
      
      





 class CreateDefinitions < ActiveRecord::Migration def change create_table :definitions do |t| t.string :word_id, null: false t.timestamps null: false end add_index :definitions, :word_id end end
      
      





モデルは、コミュニケーションや言葉の主キーを示します。



 class Word < ActiveRecord::Base self.primary_key = 'word' has_many :definitions end
      
      





 class Definition < ActiveRecord::Base belongs_to :word end
      
      





これで十分です。移行や同様の松葉杖で実行を実行する必要はありません。 受け取ったことを確認します。



 w = Word.create(word: 'hello') #<Word word: "hello", created_at: "2015-03-16 21:35:59", updated_at: "2015-03-16 21:35:59">
      
      



') w = Word.create(word: 'hello') #<Word word: "hello", created_at: "2015-03-16 21:35:59", updated_at: "2015-03-16 21:35:59">





 Word.find('hello') Word Load (0.8ms) SELECT "words".* FROM "words" WHERE "words"."word" = $1 LIMIT 1 [["word", "hello"]] => #<Word word: "hello", created_at: "2015-03-16 21:35:59", updated_at: "2015-03-16 21:35:59">
      
      





 d = Definition.create(word: w) => #<Definition id: 2, word_id: "hello", created_at: "2015-03-16 21:36:22", updated_at: "2015-03-16 21:36:22">
      
      





 w.definitions => #<ActiveRecord::Associations::CollectionProxy [#<Definition id: 2, word_id: "hello", created_at: "2015-03-16 21:36:22", updated_at: "2015-03-16 21:36:22">]>
      
      





 d.word => #<Word word: "hello", created_at: "2015-03-16 21:35:59", updated_at: "2015-03-16 21:35:59">
      
      





 d.word_id => "hello"
      
      





 w.id => "hello
      
      





モデルの主キーを変更しましたが、何も壊れていません。 ところで、最後の例は困惑するかもしれません。 任意のスキーム場合はそこにそのベースに、IDをどこにいますか? フードの下に隠されているものは次のとおりです。



 # activerecord/lib/active_record/attribute_methods/primary_key.rb:17 def id sync_with_transaction_state read_attribute(self.class.primary_key) end
      
      



/ primary_key.rb: # activerecord/lib/active_record/attribute_methods/primary_key.rb:17 def id sync_with_transaction_state read_attribute(self.class.primary_key) end





あなただけの「プロキシ»PRIMARY_KEYフィールド、idフィールドを見ることができるように。



All Articles