読者です 読者をやめる 読者になる 読者になる

Rails4をJSON APIとして構築していてCreateのAPIに関連のID一覧をparameterとしてPOSTしてはまった

Rails

前提

1.Railsのwrap_parametersはJSONRailsへ送った時にルート要素を省いてくれる。というか、省いて送ってもよしなにwrapしてくれる。

Railsのwrap_parametersは何をしてくれるのか?

2.has_manyを定義するとrelation_ids,relation_ids=というメソッドが使えるようになる

#group.rb
Class Group
  has_many :groups_users
  has_many :users, through: :groups_users
end
#user.rb
class User
  has_many :groups_users
  has_many :groups, through: :groups_users
end
#irb
group = Group.first
group.user_ids
# =>[1,2,3]
group.user_ids=[2,3,4]

3.Railsのstrong_parametersは許可されたパラメータ以外を取り除く

#groups_controller.rb
class GroupsController < ApplicationController
  def create
    @group = Group.new(group_params)
    # 省略
  end

  private
  def group_params
    params.require(:group).permit(:name, user_ids: [])
  end
end

問題

このgroups#createに対して以下のようなJSONを送付したところ、groupモデルは作成されたが、userとの関連は作成されなかった。

// json
{
  name: "新規グループ",
  user_ids: [1,2,3]
}

user_idsがstrong_parametesに書いたにもかかわらず弾かれる。

実際のparamsを見るとこんな感じ

 Parameters: {"name"=>"新規グループ", "user_ids"=>[1,2,3], "group"=>{"name"=>"新規グループ"}}

調べるとどうもnested_attributes_forも引っかかるようだ。

解決

strong_paramtersのREADMEに書いてあった。

以下のようにrequire(:group)を取り除く

# groups_controller.rb
class GroupsController < ApplicationController
  # 省略

  private
  def group_params
    params.permit(:name, user_ids: [])
  end
end

これで、wrap_parametersもきき、groupとuserの関連も作成される。