LoginSignup
0
0

More than 5 years have passed since last update.

cocoonで1対多対1のフォームを作ろうとしたときの話

Posted at

概要

cocoonで関連モデルも含めたformを作ることができるが、1対多対1のような、関連先の更に先の関連まで含めたフォームを作るためのTipsがあまりなかった&うまくできない部分もあったので、ここに残しておきます。

cocoonで1対多対1のフォームを作る

コントローラー、ビュー、モデルそれぞれに分けて書いていきます。

モデル

class Parent < ApplicationRecord

  has_many :children, dependent: :restrict_with_exception, inverse_of: :parent
  accepts_nested_attributes_for :children, allow_destroy: true
end

class Child < ApplicationRecord

  belongs_to :parent
  has_one :grand_son, dependent: restrict_with_exception, inverse_of: :child
  accepts_nested_attributes_for :grand_son, allow_destroy: true
end

class GrandSon < ApplicationRecord

  belongs_to :child
end

親側にaccepts_nested_attributes_forをつければいいだけです。
cocoonのREADMEに書いてあるとおりですね。

コントローラー

class ParentsController < ApplicationController

  # 詳細は省略
  def create
    @parent = Parent.create!(parent_params)
  end

  private

  def parent_params
    params.require(:parent).permit(
      :name,
      children_attributes: [
        :id,
        :name,
        :_destroy,
        {
          grand_son_attributes: [
            :id,
            :name,
          ],
        },
      ])
  end
end

以上のような形で、ストロングパラメーターにxxx_attributesを孫のモデルまで一気に書いてしまいます。
これで一気に孫のモデルまで登録できるようになります。

ビュー

問題はビューです。

このWikiによれば、force_non_association_createtrueにしてしまえば、1個しか追加できないようなのですが、子と孫が1対1の関係の場合は、複数個追加できてしまいます。
これでは狙ったとおりにできないので、自分は以下のように対応しました。

application.js
$('#children')
  .on('cocoon:after-insert', function () {
    $(this).css('cssText', 'display: none !important');
});

上記のようにすることで、追加ボタンを押した際に、その追加ボタンを消してしまうことができます。
ただ、すごくかっこ悪いので、いい方法があれば、ご教示いいただけますと幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0