箱のプログラミング日記。

渋谷の自社開発企業でRails書いてます。

カラムにreferencesの指定ができない【MySQL文法エラー】

f:id:y_hakoiri:20191102134313j:plain

カラムに外部キー制約をつけようとしたところうまくいかなかったので、

解決方法を残しておこうと思います。

 

実現したかったこと

postテーブルを作成後、複数のカラムを追加

その際、外部キー制約を設定するカラムが含まれていたが、エラーになる

 

テーブルはもともと作っていたので

$ rails g migration AddColumnToPost

 

↓マイグレーションファイル

def change
 add_column :posts, :product_name, :string, null: false
 add_column :posts, :product_description, :text, null: false
 add_column :posts, :first_category_id, :integer, null: false
 add_column :posts, :second_category_id, :integer, null: false
 add_column :posts, :third_category_id, :integer
 add_column :posts, :brand_id, :references, foreign_key:true
add_column :posts, :product_size, :integer
 add_column :posts, :product_condition, :integer, null: false
 add_column :posts, :delivery_fee, :integer, null: false
 add_column :posts, :delivery_former_area, :string, null: false
 add_column :posts, :delivery_date, :integer, null: false
 add_column :posts, :product_price, :integer, null: false
 add_column :posts, :product_status, :integer, null: false
end

 

エラー文↓

Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'references' at line 1: ALTER TABLE `posts` ADD `brand_id` references

 

referencesが怒られてるなーなるほど。

MySQLの文法エラーということは分かった

バージョンが関係しているかな?と思って色々調べるもそれらしきヒントはヒットせず。

(ちなみに、エラーで引っかかったbrandより前のカラムだけ追加されました)

 

試したこと

とりあえず、referencesにしてるのに外部キーの元がないのが原因なのかなと思い

先にbrandテーブルを作って同じことを実行してみたが、変わらず。

 

解決方法

referencesはt.の形で指定しないと文法エラーになるらしい。

 

上記のように、他のカラムと同じような序列で指定はできないみたい。

ということで、先にreferences以外のカラムを一気に追加

def change
 add_column :posts, :product_name, :string, null: false
 add_column :posts, :product_description, :text, null: false
 add_column :posts, :first_category_id, :integer, null: false
 add_column :posts, :second_category_id, :integer, null: false
 add_column :posts, :third_category_id, :integer
 add_column :posts, :product_size, :integer
 add_column :posts, :product_condition, :integer, null: false
 add_column :posts, :delivery_fee, :integer, null: false
 add_column :posts, :delivery_former_area, :string, null: false
 add_column :posts, :delivery_date, :integer, null: false
 add_column :posts, :product_price, :integer, null: false
 add_column :posts, :product_status, :integer, null: false
end
 
で次にreferenceを追加
 
$ rails g migration AddReferencesToPost
(ここのreferencesはあくまでも「何をするマイグレーションファイルなのか」
というのを表すためのものなので、必ずしもreferencesである必要はない)
 
↓マイグレーションファイル
class AddReferencesToPost < ActiveRecord::Migration[5.2]
 def change
  change_table :posts do |t|
   t.references :brand, foreign_key: true
  end
 end
end
 
こうするとreferencesの指定が効いて、brand_idカラムが出来上がった

https://i.gyazo.com/12a194abb4f8115611fcf19e6b2a276e.png

 

まとめ

  • referencesを追加したい時はt.の形でしか追加できない
  • references :参照するモデル名 とすると自動的にモデル名_idカラムが生成される
 

以下参照