LoginSignup
35
37

More than 5 years have passed since last update.

ネストされたモデル(親子関係を持つモデル)でStrongParameterを利用する

Last updated at Posted at 2014-05-09

ネストされたモデルを利用しようとして、StrongParameterの設定やビュー周りに???となったので、使い方を整理してみました。

前提

モデル

利用するモデルです。
※の属性は、accept_nested_attributes_forも利用しています。

Account
id
email
※(has many enquates)
Enquate
id
owner_id: Account
title
※(has many questions)
(belongs to account)
Question
id
enquate_id
(belongs_to enquate)

StrongParameterオブジェクトの生成方法

raw_params = {id: 1, owner_id: 2}
strong_params = ActionController::Parameters.new(raw_params)
enquate = Enquate.new(strong_params.permit(:id,:owner_id))

子のStrongParameterオブジェクトを取得する。 require

raw_params = {enquate: {id: 1, owner_id: 2}}
strong_params = ActionController::Parameters.new(raw_params)
enquate_params = strong_params.require(:enquate)
enquate_params.class # これもActionController::Parameters
enquate_params # {id: 1, owner_id: 2}

accepts_nested_attributes_for時のkey

属性名_attributesになる。

class Enquate < ActiveRecord::Base
  has_many :questions
  accepts_nested_attributes_for :questions # questions_attributesがkeyとなる{ questions_attributes: [{:content}]} 
end

準備はここまで。

StrongParameterからのパラメータ取得方法

パラメータを無条件で許可する. permit!

pemit!は全てのパラメータを取得可能な状態にする。
通常使わない。(けど一番動作確認しやすい)

ネストされていないパラメータに対しての動作確認

raw_params = {id: 1, owner_id: 2}
strong_params = ActionController::Parameters.new(raw_params)
enquate = Enquate.new(strong_params.permit!) # ok
enquate = Enquate.new(strong_params) # ok 一度permit!しているため。

ネストされているパラメータに対しての動作確認

# 全体を許可する場合
def permit_all
  raw_params = {enquate: {id: 1, owner_id: 2}}
  strong_params = ActionController::Parameters.new(raw_params)
  enquate = Enquate.new(strong_params.permit!) # ok
  enquate = Enquate.new(strong_params.require(:enquate)) # ok
end

# :eqnuateのみ許可する場合
def permit_part
  raw_params = {enquate: {id: 1, owner_id: 2}}
  strong_params = ActionController::Parameters.new(raw_params)
  enquate = Enquate.new(strong_params.require(:enquate).permit!) # ok
  enquate = Enquate.new(strong_params.require(:enquate)) # ok

end

指定したパラメータのみ許可する。 permit(:param1, param2)...

raw_params = {id: 1, owner_id: 2}
strong_params = ActionController::Parameters.new(raw_params)
enquate = Enquate.new(strong_params.permit(:id, :owner_id) # ok
enquate = Enquate.new(strong_params) # ng

ネストされたパラメータを取得する。(has_oneの場合)

未確認です。

ネストされたパラメータを許可する。(has_manyの場合) {key: [:param1,:param2...]}

# リクエストパラメータ単体の確認
raw_params = {enquate: {id: 1, questions_attributes: [{content: "test1"},{content: "test2"}]}}
e = Enquate.new(raw_params)
# StrongParameter
strong_params = ActionController::Parameters.new(raw_params)
e = Enquate.new(strong_params.require(:enquate).permit(:id, questions_attributes: [:content]))

ビュー

これから調査予定...

このあたりが参考になりそうです。
Rails4で 1対多、多対多関連しているときのフォームを作るなら、Nested Form Gemが便利

参考

github strong parameter
rails api ActiveRecord Nested Attributes
rails guide ActionController overview

余談

  • ActiveRecord.attribute_namesで属性名一覧が取得できる。(例Enquate.attribute_names)
  • 1つ1つ分解して理解すると簡単。いっきに全部理解しようとすると大変。というか私の頭では無理でした。。。
35
37
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
35
37