ЯoomeR

プログラミング~実装とエラー解決と、時々、AI~

active_hashのカラム名に「_id」はなぜ必要なのか?

使用例

住所を保存するテーブルがあり、都道府県をactive_hashを使用して保存するものとする。

class CreateAddresses < ActiveRecord::Migration[6.0]
  def change
    create_table :addresses do |t|
      t.string :postal_code, null: false
      t.integer :prefecture_id, null: false
      t.timestamps
    end
  end
end
class Prefecture > ActiveHash::Base
  self.data = [
    { id: 1, name: "北海道" }, { id: 2, name: "青森県" }, { id: 3, name: "岩手県" },
    { id: 4, name: "宮城県" }, { id: 5, name: "秋田県" }, { id: 6, name: "山形県" },
    { id: 7, name: "福島県" }, { id: 8, name: "茨城県" }, { id: 9, name: "栃木県" },
    { id: 10, name: "群馬県" }, { id: 11, name: "埼玉県" }, { id: 12, name: "千葉県" },
    { id: 13, name: "東京都" }, { id: 14, name: "神奈川県" }, { id: 15, name: "新潟県" },
    { id: 16, name: "富山県" }, { id: 17, name: "石川県" }, { id: 18, name: "福井県" },
    { id: 19, name: "山梨県" }, { id: 20, name: "長野県" }, { id: 21, name: "岐阜県" },
    { id: 22, name: "静岡県" }, { id: 23, name: "愛知県" }, { id: 24, name: "三重県" },
    { id: 25, name: "滋賀県" }, { id: 26, name: "京都府" }, { id: 27, name: "大阪府" },
    { id: 28, name: "兵庫県" }, { id: 29, name: "奈良県" }, { id: 30, name: "和歌山県" },
    { id: 31, name: "鳥取県" }, { id: 32, name: "島根県" }, { id: 33, name: "岡山県" },
    { id: 34, name: "広島県" }, { id: 35, name: "山口県" }, { id: 36, name: "徳島県" },
    { id: 37, name: "香川県" }, { id: 38, name: "愛媛県" }, { id: 39, name: "高知県" },
    { id: 40, name: "福岡県" }, { id: 41, name: "佐賀県" }, { id: 42, name: "長崎県" },
    { id: 43, name: "熊本県" }, { id: 44, name: "大分県" }, { id: 45, name: "宮崎県" },
    { id: 46, name: "鹿児島県" }, { id: 47, name: "沖縄県" }
  ]
end

前提知識:なぜinteger型なのか?

あくまで保存するのは「idの数値情報」であるから。

そこからアソシエーションを使用して他の情報(今回の場合、都道府県名)を引き出している。

ちなみに、active_hashではreference型は使用できないので注意が必要だ。

なぜ「_id」が必要なのか?

prefecture_idカラムそのものが「id」として機能するからである。

idがない場合は以下のようにエラーが発生する。

(belongs_to_active_hashが絡んでいるように考えられる・・・)

class CreateAddresses < ActiveRecord::Migration[6.0]
  def change
    create_table :addresses do |t|
      t.string :postal_code, null: false
      t.integer :prefecture, null: false
      t.timestamps
    end
  end
end
undefined method "prefecture_id" for <Prefecture:0xxxxxxxxxxxx>