От Ember к JSON API с Rails 5 и active_model_serializers — как анализировать хеш параметров в контроллере Rails

Я следовал настройкам, описанным в Руководство по active_model_serializers для сопряжения API Rails 5 с приложением Ember 3. В Rails ShopLanguagesController я изменил метод shop_language_params, как описано в приведенном выше руководстве:

private

  def shop_language_params
    #params.require(:shop_language).permit(:shop_id, :language_id, :modified_by)
    ActiveModelSerializers::Deserialization.jsonapi_parse!(params, only: [:shop_id, :language_id, :modified_by] )
  end

Вот что я получаю, когда публикую следующие данные из приложения Ember (видно в консоли журнала Rails):

Started POST "/shops/613/languages" for 127.0.0.1 at 2018-04-09 16:53:05 +0200
Processing by ShopLanguagesController#create as JSONAPI
  Parameters: {"data"=>{"attributes"=>{"modified_by"=>"Z28SCAMB"}, "relationships"=>{"shop"=>{"data"=>{"type"=>"shops", "id"=>"613"}}, "language"=>{"data"=>{"type"=>"languages", "id"=>"374"}}}, "type"=>"shop-languages"}, "shop_id"=>"613"}
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."username" = $1 LIMIT $2  [["username", "Z28SCAMB"], ["LIMIT", 1]]
  Shop Load (0.4ms)  SELECT  "shops".* FROM "shops" WHERE "shops"."id" = $1 LIMIT $2  [["id", 613], ["LIMIT", 1]]
++++ params: {:modified_by=>"Z28SCAMB"}

Опубликованные данные кажутся правильными. Как извлечь нужные параметры (например, language_id) из этого JSON?


person belgoros    schedule 09.04.2018    source источник


Ответы (2)


Разобрать JSON в Rails довольно просто:

parsed_json = ActiveSupport::JSON.decode(your_json_string)

Предположим, объект, с которым вы хотите связать shortUrl, — это объект Site, который имеет два атрибута — short_url и long_url. Затем, чтобы получить shortUrl и связать его с соответствующим объектом сайта, вы можете сделать что-то вроде:

parsed_json["results"].each do |longUrl, convertedUrl|
  site = Site.find_by_long_url(longUrl)
  site.short_url = convertedUrl["shortUrl"]
  site.save
end
person Mauricio Gracia Gutierrez    schedule 09.04.2018
comment
Спасибо, Маурисио за ответ. Больше всего меня смущает отсутствие примеров и документации на стороне Rails. Я полагал, что гем active_model_serializers будет достаточно умен, чтобы выполнить весь этот сложный анализ. Если нет, то в контроллере не так много полезности. - person belgoros; 09.04.2018

Решение, которое сработало для меня, состояло в том, чтобы изменить частный метод shop_language_params в ShopLanguagesController следующим образом:

def shop_language_params
    ActiveModelSerializers::Deserialization.jsonapi_parse!(params, only: [:shop, :language, :modified_by] )
end

Как видите, я разрешаю не значения внешних ключей для магазина и языка (shop_id и language_id), а сами объекты: :shop и :language. Теперь у вас есть значения shop_id и language_id, доступные в хэше params, как обычно.

И, конечно же, вы должны вызывать shop_language_params везде в контроллере, где вам нужно передать параметры shop_language. Пример, где я нахожу язык в том же контроллере:

private 

def find_language
    @language = Language.find_by!(id: shop_language_params[:language_id])
end
person belgoros    schedule 10.04.2018