2013-04-28 54 views
1

我有一个叫做App.Routine的has_many活动的嵌套资源。当我发的帖子这里是我的有效载荷:发布从Ember.js到Rails API的嵌套资源失败。

{程序:{名称:测试名,活动内容:[{名称:测试名},{名称:测试名}]}}

这将返回500错误:

的ActiveRecord :: AssociationTypeMismatch在RoutinesController#创建

活动(#32627220)预计,得到的ActiveSupport :: HashWithIndifferentAccess(#33577656)

我的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

你有没有解决这个问题。有类似的问题? – Undistraction 2013-05-12 17:40:49

+0

@Pedr - 可惜没有。它似乎是Rails不接受我发送的JSON的问题。如果我从App.store中删除了{embedded:'always'},则会为具有“parent_id”的子级的父级和子级发送2个单独的JSON帖子。以这种方式提交我的POST是成功的,但是我只想发送带有嵌入式父/子对象的1帖子。遵循这个例子[https://github.com/dgeb/ember_data_example](https://github.com/dgeb/ember_data_example),我不知道我在做什么不同,会导致错误。 – kevinml 2013-05-19 18:50:49

+0

耻辱。感谢更新。 – Undistraction 2013-05-19 19:12:28

回答

0

我的原始问题确实是与我的Rails API。我再次追踪@ dgeb的例子,并意识到我对强参数知之甚少。谢天谢地,这里有一个Railscast!一旦我正确实施,我很好去!

在我的Gemfile中添加了“gem strong_parameters”。然后,我父控制器上的#create函数调用update_parameters函数,我首先创建并保存父项,然后遍历子项并保存它。

从丹·格布哈特的烬数据例如:

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