Каков точный способ создания модели данных Geo Json в Rails API с использованием Mongoid ORM? - PullRequest
1 голос
/ 14 июля 2020

Мне просто любопытно, как обрабатывать вложенные json объекты с помощью mongoid, полагая, что это возможно. Вот пример данных Geo Json из моего внешнего приложения:

{
    "type": "Feature",
    "properties": {
        "name": "A Cool Feature",
        "amenity": "A Cool Label",
        "popupContent": "This is a cool area.."
    },
    "geometry": {
        "type": "polygon",
        "coordinates": [
            {
                "lat": 41.47566020027821,
                "lng": 269.65942382812506
            },
            {
                "lat": 40.17047886718111,
                "lng": 266.81396484375006
            },
            {
                "lat": 38.41055825094609,
                "lng": 268.86840820312506
            },
            {
                "lat": 38.24680876017446,
                "lng": 270.91186523437506
            },
            {
                "lat": 40.871987756697415,
                "lng": 271.57104492187506
            }
        ]
    }
}

А вот мой контроллер (очень базовый c один)

class Api::V1::GeoDataController < ApplicationController

  # GET /geo_data
  def index
    @geo_data = GeoDatum.all
    render json: @geo_data
  end
  
  # POST /geo_data
  def create
    @geo_datum = GeoDatum.new(geo_datum_params)
    if @geo_datum.save
      render json: @geo_datum
    else
      render error: { error: 'Unable to create GeoDatum.' }, status: 400
    end    
  end
  
  private

  def geo_datum_params
    params.require(:geo_datum).permit(:type, :properties, :geometry)
  end

end

Модели здесь:

class GeoDatum
  include Mongoid::Document
  include Mongoid::Timestamps
  field :type, type: String
  field :properties, type: Property
  field :geometry, type: Geometry

  embeds_one :properties, class_name: "Property"
  embeds_one :geometry, class_name: "Geometry"
end

class Property
  include Mongoid::Document
  field :name, type: String
  field :amenity, type: String
  field :popupContent, type: String

  embedded_in :geo_datum, class_name: "GeoDatum"
end

class Geometry
  include Mongoid::Document
  field :type, type: String
  field :coordinates, type: Array

  embeds_many :coordinates, class_name: "LatLng"
  embedded_in :geo_datum, class_name: "GeoDatum"
end

class LatLng
  attr_reader :longitude, :latitude

  def initialize(lng, lat)
    @longitude = lng
    @latitude = lat
  end

  embedded_in :geometry, class_name: "Geometry"
end

Вот журнал консоли для запроса POST:

Started POST "/api/v1/geo_data" for 192.168.1.209 at 2020-07-13 21:58:53 +0000
Processing by Api::V1::GeoDataController#create as */*
  Parameters: {"type"=>"Feature", "properties"=>{"name"=>"A Cool Feature", "amenity"=>"A Cool Label", "popupContent"=>"This is a cool area.."}, "geometry"=>{"type"=>"polygon", "coordinates"=>[{"lat"=>41.47566020027821, "lng"=>269.65942382812506}, {"lat"=>40.17047886718111, "lng"=>266.81396484375006}, {"lat"=>38.41055825094609, "lng"=>268.86840820312506}, {"lat"=>38.24680876017446, "lng"=>270.91186523437506}, {"lat"=>40.871987756697415, "lng"=>271.57104492187506}]}, "geo_datum"=>{"type"=>"Feature", "properties"=>{"name"=>"A Cool Feature", "amenity"=>"A Cool Label", "popupContent"=>"This is a cool area.."}, "geometry"=>{"type"=>"polygon", "coordinates"=>[{"lat"=>41.47566020027821, "lng"=>269.65942382812506}, {"lat"=>40.17047886718111, "lng"=>266.81396484375006}, {"lat"=>38.41055825094609, "lng"=>268.86840820312506}, {"lat"=>38.24680876017446, "lng"=>270.91186523437506}, {"lat"=>40.871987756697415, "lng"=>271.57104492187506}]}}}
Unpermitted parameters: :properties, :geometry
MONGODB | [11] 172.17.0.1:27017 #1 | leaflet.insert | STARTED | {"insert"=>"geo_data", "ordered"=>true, "documents"=>[{"_id"=>BSON::ObjectId('5f0cd91d44041302afa3ea2a'), "type"=>"Feature", "updated_at"=>2020-07-13 21:58:53.921377228 UTC, "created_at"=>2020-07-13 21:58:53.921377228 UTC}], "$db"=>"leaflet", "lsid"=>...
MONGODB | [11] 172.17.0.1:27017 | leaflet.insert | SUCCEEDED | 0.005s
Completed 200 OK in 14ms (Views: 0.7ms | MongoDB: 0.0ms | Allocations: 1098)

Дело в том, что происходит Unpermitted parameters:: properties,: geometry , эти атрибуты совсем не кормят. Любая помощь приветствуется.

1 Ответ

0 голосов
/ 14 июля 2020

, если вам нужен вложенный объект (ы), вы оборачиваете его внутри ha sh или массива ... вот так

params.require(:foo).permit(:type, :properties => [:name, :amenity, :popUpContent], geometry: [:type, { coordinates: [:lat, :lng] }])

см. do c

...