【问题标题】:Parsing multiple json objects and saving them in Rails 4解析多个 json 对象并将它们保存在 Rails 4 中
【发布时间】:2015-06-14 13:00:03
【问题描述】:

我有 curl 命令:

 curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{
"map":
     {"lat":"123.45543","lon":"45.43424","vibration_level":"456","time_sent":"20.05.1994" } 
}' http://localhost:3000/maps

在我的创建控制器方法中,我有:

def create
    @map = Map.new(map_params)
    respond_to do |format|
      if @map.save
        format.json {
          render :show, status: :created, location: @map
        }
      else
        format.json { render json: @map.errors, status: :unprocessable_entity }
      end
    end
  end

这个方法是脚手架的。 Rails 自动将我的 JSON 转换为哈希并将其正确保存到我的数据库中。但是,如果我有多个这样的 JSON 对象,我该如何解析 JSON:

curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{
"map":
{"lat": "51.088672", "lon": "71.396522", "vibration_level": "300", "time_sent": "07:25:00"},
{"lat": "51.088672", "lon": "71.396453", "vibration_level": "300", "time_sent": "07:25:01"},
{"lat": "51.088829", "lon": "71.396476", "vibration_level": "300", "time_sent": "07:25:14"} 
}' http://localhost:3000/maps

当我尝试该命令时,我得到一个解析错误。

编辑: maps_controller.rb

class MapsController < ApplicationController
  before_action :set_map, only: [:show, :edit, :update, :destroy]
  skip_before_filter  :verify_authenticity_token
  before_action :parse_json_data_to_params, except: [ :index,:new,:edit,:show ]

  # GET /maps
  # GET /maps.json
  def index
    @coords = Map.all
  end

  # GET /maps/1
  # GET /maps/1.json
  def show
  end

  # GET /maps/new
  def new
    @map = Map.new
  end

  # GET /maps/1/edit
  def edit
  end

  # POST /maps
  # POST /maps.json
  def create      
    @map = Map.new(map_params)
       respond_to do |format|
      if @map.save
        format.json {
          render :show, status: :created, location: @map
        }
      else
        format.json { render json: @map.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /maps/1
  # PATCH/PUT /maps/1.json
  def update
    respond_to do |format|
      if @map.update(map_params)
        format.html { redirect_to @map, notice: 'Map was successfully updated.' }
        format.json { render :show, status: :ok, location: @map }
      else
        format.html { render :edit }
        format.json { render json: @map.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /maps/1
  # DELETE /maps/1.json
  def destroy
    @map.destroy
    respond_to do |format|
      format.html { redirect_to maps_url, notice: 'Map was successfully destroyed.' }
      format.json { head :no_content }
    end
  end


  private
    # Use callbacks to share common setup or constraints between actions.
    def set_map
      @map = Map.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def map_params
      params.permit(maps: [:lat, :lon, :vibration_level, :time_sent])
    end

  def parse_json_data_to_params
    params.merge!(ActiveSupport::JSON.decode(request.raw_post))
  end

end
编辑2:

Started POST "/maps" for ::1 at 2015-06-14 20:56:57 +0600
Processing by MapsController#create as JSON
  Parameters: {"maps"=>[{"lat"=>"51.088672", "lon"=>"71.396522", "vibration_level"=>"300", "time_sent"=>"07:25:00"}, {"lat"=>"51.088672", "lon"=>"71.396453", "vibration_level"=>"300", "time_sent"=>"07:25:01"}, {"lat"=>"51.088829", "lon"=>"71.396476", "vibration_level"=>"300", "time_sent"=>"07:25:14"}], "map"=>{}}
Unpermitted parameter: map
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
Completed 422 Unprocessable Entity in 8ms (Views: 0.2ms | ActiveRecord: 0.7ms)

【问题讨论】:

    标签: ruby-on-rails json


    【解决方案1】:

    在这种情况下,您也可以通过@maps = Map.create(map_params) 简单地创建它们,但是现在 - 您需要更改map_params 方法的定义,这是必须的。

    方法如下:

    def map_params
      params.permit(maps: [:lat, :lon, :vibration_level, :time_sent])
    end
    

    还有一件事:将attr_accessor: maps 添加到您的模型类中:

    def Map < ActiveRecord::Base
      attr_accessor :maps
      # other code
    end
    

    编辑:

    您在 JSON 末尾传递 "map"=&gt;{},这就是您看到错误的原因。

    【讨论】:

    • 我认为这应该可行,但我得到一个 ActionDispatch::ParamsParser::ParseError (795: unexpected token at.
    • 您能否将问题中的完整错误和控制器代码作为编辑发布?
    • 当您执行curl 命令时,请尝试发送maps 而不是map。因为这是您的控制器所期望的。
    • 我在 jsonlint 中检查了我的 json,发现其中有一些错误。修复它并更改地图->地图后,我遇到了另一个错误。特别是我有地图参数以某种方式添加到我的参数中。我编辑了我的帖子。
    • @yerassyl 这是 Rails 的一个特性。约定是创建和更新操作的输入参数包装在顶级键中,其名称源自与控制器对应的模型的名称。例如:在您的MapsController 中,模型为Map,参数中的顶级键为map。如果缺少这个顶级键,Rails 会自动添加它并复制该键中的整个 params 哈希。如果你愿意,你可以禁用它:api.rubyonrails.org/classes/ActionController/ParamsWrapper.html 不过它基本上是无害的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 2014-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多