柳屋

ソースコードのリファクタからよもやままで

rails5で中間テーブルの登録

rails5で中間テーブルの登録時にハマったので備忘録として書いておきます

モデルの関係は以下前提とします

Item <=> ItemCategory <=> Category

Activerecodeの設定

それぞれのモデルに多対多の設定をします

item.rb

class Item < ApplicationRecord
    has_many :item_categories
    has_many :categories, through: :item_categories
end

category.rb

class Category < ApplicationRecord
    has_many :item_categories
    has_many :items, through: :item_categories
end

item_category.rb

class ItemCategory < ApplicationRecord
  belongs_to :item
  belongs_to :category
end

has_manyの記述の順番を間違えるとDB登録時に ActiveRecord::HasManyThroughOrderError: Cannot have a has_many :through association 'Item#categories' which goes through 'Item#item_categories' before the through association is defined.

のエラーが出るので注意! これでめちゃめちゃハマりましたw

中間テーブルに登録

上記設定が終わったのでrails コンソール上で登録のテストをやってみます

まずはitemとcategoryに登録します

item = Item.create(name: "アイテム名")
category = Category.create(name: "カテゴリー名")

中間テーブルに登録するときは上記実行後に以下を実行します

item.categories.create(name: "カテゴリー名")
;(function(document){ var pres = document.getElementsByTagName("pre") for(var i=pres.length; i--; ){  var el = makeOl(pres[i]) pres[i].appendChild(el) } function makeOl(pre){ if (pre.className.indexOf("gist") !== -1) { return } var ol = document.createElement("ol") , li = document.createElement("li") , df = document.createDocumentFragment() , br = pre.innerHTML.match(/\n/g) || 0 ol.className = "preLine" ol.setAttribute("role", "presentation") // no lang, no line-number if( pre.className && ! /lang-./.test(pre.className) ){ br.length += 1 } for(var i=br.length; i--; ){ var li2 = li.cloneNode(true) df.appendChild(li2) } ol.appendChild(df) return ol } })(document)