使用从Ember.js到Rails API的嵌套资源失败。

时间:2013-04-28 20:47:14

标签: ruby-on-rails ember.js

我有一个名为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中的活动哈希,但我无法弄清楚处理这个问题的正确方法。

1 个答案:

答案 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