如何将JSON传递给RAILS应用程序,以便它在一个has_many关系中创建嵌套的子对象?

Here's what I have so far:

两个模型对象.

class Commute < ActiveRecord::Base
  has_many :locations
  accepts_nested_attributes_for :locations, :allow_destroy => true
end

class Location < ActiveRecord::Base
  belongs_to :commute
end

对于通勤,我设置了一个标准控制器.我希望能够使用JSON在一个REST调用中创建一个通勤对象以及几个子位置对象.我一直在try 这样的事情:

curl -H "Content-Type:application/json" -H "Accept:application/json" 
-d "{\"commute\":{\"minutes\":0, 
\"startTime\":\"Wed May 06 22:14:12 EDT 2009\", 
\"locations\":[{\"latitude\":\"40.4220061\",
\"longitude\":\"40.4220061\"}]}}"  http://localhost:3000/commutes

或者更具可读性,JSON是:

{
    "commute": {
        "minutes": 0,
        "startTime": "Wed May 06 22:14:12 EDT 2009",
        "locations": [
            {
                "latitude": "40.4220061",
                "longitude": "40.4220061"
            }
        ]
    }
}

When I execute that, I get this output:

Processing CommutesController#create (for 127.0.0.1 at 2009-05-10 09:48:04) [POST]
  Parameters: {"commute"=>{"minutes"=>0, "locations"=>[{"latitude"=>"40.4220061", "longitude"=>"40.4220061"}], "startTime"=>"Wed May 06 22:14:12 EDT 2009"}}

ActiveRecord::AssociationTypeMismatch (Location(#19300550) expected, got HashWithIndifferentAccess(#2654720)):
  app/controllers/commutes_controller.rb:46:in `new'
  app/controllers/commutes_controller.rb:46:in `create'

看起来像是读取了locations JSON数组,但没有被解释为Location对象.

我可以很容易地更改客户端或服务器,因此解决方案可以来自任何一方.

So, does RAILS make this easy for me to do? Or do I need to add in some support for this to my Commute object? Perhaps add a from_json method?

Thanks for any help.


As I've been working through this, one solution that works is to modify my controller. But this doesn't seem the "rails" way of doing it, so please still let me know if there's a better way.

def create
    locations = params[:commute].delete("locations");
    @commute = Commute.new(params[:commute])

    result = @commute.save

    if locations 
      locations.each do |location|
        @commute.locations.create(location)
      end
    end


    respond_to do |format|
      if result
        flash[:notice] = 'Commute was successfully created.'
        format.html { redirect_to(@commute) }
        format.xml  { render :xml => @commute, :status => :created, :location => @commute }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @commute.errors, :status => :unprocessable_entity }
      end
    end
  end

推荐答案

Figured it out, the locations object should have been called locations_attributes to match up with the Rails nested object creation naming scheme. After doing that, it works perfectly with a default Rails controller.

{
    "commute": {
        "minutes": 0,
        "startTime": "Wed May 06 22:14:12 EDT 2009",
        "locations_attributes": [
            {
                "latitude": "40.4220061",
                "longitude": "40.4220061"
            }
        ]
    }
}

Json相关问答推荐

无法根据vega规范中的条件设置文本 colored颜色

将json数组反序列化为选项 struct

筛选JSON数组以使用Jolt仅保留具有最新日期/时间的条目

JSON API返回多个数组,需要帮助拼合数据以存储在SQL Server数据库表中

当由.sh脚本执行时,AWS查询字符串不会提取任何数据

当列为空时从 SQL 获取 JSON

转换为Json时忽略内部对象中的数组

我如何将 JSON 格式与 flutter 一起使用?帮助使用 Gamebanana api

转义 Haskell 记录的字段

N1QL 搜索对象内的某些对象

Jolt - 在同一级别添加时组合值的问题

如何为所有 API 端点全局设置 http.ResponseWriter Content-Type 标头?

错误字符串的长度超过了maxJsonLength属性设置的值

在自定义 JsonConverter 的 ReadJson 方法中处理空对象

Sequelize - 如何仅返回数据库结果的 JSON 对象?

如何在 Python 中合并两个 json 字符串?

Gson 将一组数据对象转换为 json - Android

C++:使用 nlohmann json 从文件中读取 json 对象

如何从 github API 解析链接头

log4j 支持 JSON 格式吗?