我有一个名为App.Routine的嵌套资源,其中包含has_many活动。当我发送帖子时,这是我的有效载荷:
{例程:{name:testName,activities:[{name:testName},{name:testName}]}}
这会返回500错误:
RoutinesController中的ActiveRecord :: AssociationTypeMismatch #create
活动(#32627220)预期,获得ActiveSupport :: HashWithIndifferentAccess(#33577656)
My Rails API正在使用ActiveModelSerializers:
class RoutineSerializer < ActiveModel::Serializer
attributes :id, :name
has_many :activities, embed: :ids
end
class RoutinesController < ApplicationController
respond_to :json
def create
routine = Routine.create(params[:routine])
end
我相信我的问题在于如何在routines_controller.rb中处理创建操作。 Rails不喜欢我如何返回例程JSON中的活动哈希,但我无法弄清楚处理这个问题的正确方法。
答案 0 :(得分:0)
我的原始问题确实存在于我的Rails API中。我再次关注@dgeb的例子,发现我对强参数知之甚少。谢天谢地,有一个Railscast!一旦我正确实施,我很高兴去!
在我的Gemfile中添加了'gem strong_parameters'。然后,父控制器上的#create函数调用update_parameters函数,我首先创建并保存父项,然后遍历子项并保存它。
来自Dan Gebhart的余烬数据示例:
def permitted_params
params.require(:contact).permit(:first_name,
:last_name,
:email,
:notes,
phone_numbers: [:id, :number])
end
def update_contact(contact)
contact_params = permitted_params
phone_numbers_param = contact_params.extract!(:phone_numbers)
phone_numbers_param = phone_numbers_param[:phone_numbers]
phone_numbers_param ||= []
# Because updates to the contact and its associations should be atomic,
# wrap them in a transaction.
Contact.transaction do
# Update the contact's own attributes first.
contact.attributes = contact_params
contact.save!
# Update the contact's phone numbers, creating/destroying as appropriate.
specified_phone_numbers = []
phone_numbers_param.each do |phone_number_params|
if phone_number_params[:id]
pn = contact.phone_numbers.find(phone_number_params[:id])
pn.update_attributes(phone_number_params)
else
pn = contact.phone_numbers.create(phone_number_params)
end
specified_phone_numbers << pn
end
contact.phone_numbers.each do |pn|
pn.destroy unless specified_phone_numbers.include?(pn)
end
end
# Important! Reload the contact to ensure that changes to its associations
# (i.e. phone numbers) will be serialized correctly.
contact.reload
return true
rescue
return false
end