Почему данные JSON-патчей из отношений не сохраняются через Ruby on Rails? - PullRequest
0 голосов
/ 23 января 2019

У меня есть API Ruby on Rails, где данные обрабатываются в JSON. Когда я хочу обновить сущность, все атрибуты постоянно обновляются, но измененные отношения не обрабатываются правильно, сущность остается такой же, как и раньше.

Данные JSON до и после PATCH:

{"data":{"id":"26","type":"candidate","attributes":
{"place":"Ort","zip_code":"PLZ","address":"Adresse",
"date_of_birth":"2019-01-01T00:00:00.000Z","title":"Frau",
"first_name":"Vorname","last_name":"Nachname",
"email_address":"email@example.ch",
"confirm_terms_and_conditions":true},"relationships": 
{"occupational_fields":{"data":[]}}}}

Ввод PATCH:

Started PATCH "/candidates/26" for 127.0.0.1 at 2019-01-22 
19:40:53 +0100
Processing by CandidatesController#update as JSON
Parameters: {"data"=>{"id"=>"26", "attributes"=>{"place"=>"Ort", 
"zip_code"=>"PLZ", "address"=>"Adresse", "title"=>"Frau", 
"first_name"=>"Vorname", "last_name"=>"Nachname", 
"email_address"=>"email@example.ch", 
"confirm_terms_and_conditions"=>true, "date_of_birth"=>"2019-01- 
01T00:00:00.000Z"}, "relationships"=>{"occupational_fields"=> 
{"data"=>[{"type"=>"occupational-fields", "id"=>“4“}]}}, 
"type"=>"candidates"}, "id"=>"26", "candidate"=>{}}

Это мои модели, Candidates и OccupationalFields связаны через отношение has_many own_to_many через одно CandidatesOccupationalField:

class Candidate < ApplicationRecord
  has_many :candidates_occupational_fields, dependent: :destroy
  has_many :occupational_fields, through: 
    :candidates_occupational_fields, dependent: :nullify
end


class CandidatesOccupationalField < ApplicationRecord
  belongs_to :candidate
  belongs_to :occupational_field
end


class OccupationalField < ApplicationRecord
  has_many :candidates_occupational_fields, dependent: :destroy
  has_many :candidates, through: :candidates_occupational_fields,
    dependent: :nullify
end

Это используемый контроллер:

class CandidatesController < ApplicationController
  before_action :set_candidate, only: %i[show update destroy]

  # GET /candidates
  def index
    @candidates = Candidate.all
    render json: CandidateSerializer.new(@candidates).serialized_json
  end

  # GET /candidates/1
  def show
    @candidate = Candidate.find(params[:id])
    render json: CandidateSerializer.new(@candidate).serialized_json
  end

  # POST /candidates
  def create
    @candidate = Candidate.new(candidate_params)

    if @candidate.save
      render json: CandidateSerializer.new(@candidate), status: :created
    else
      render json: @candidate.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /candidates/1
  def update
    @candidate = Candidate.find(params[:id])
    if @candidate.update(candidate_params)
      render json: CandidateSerializer.new(@candidate)
    else
      render status: :unprocessable_entity
    end
  end

  # DELETE /candidates/1
  def destroy
    @candidate.destroy
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_candidate
    @candidate = Candidate.find(params[:id])
  end

  # Only allow a trusted parameter "white list" through.
  def candidate_params
    params.require(:data)[:attributes]
          .permit(:place, :zip_code, :address,
                  :date_of_birth, :title, :first_name,
                  :last_name, :email_address, 
                  :confirm_terms_and_conditions,
                  occupational_field_ids: [])
  end
end

Форматирование JSON выполняется fastjsonapi, это используемые сериализаторы:

class CandidateSerializer
  include FastJsonapi::ObjectSerializer
  attributes :place, :zip_code, :address, :date_of_birth,
         :title, :first_name, :last_name, :email_address,
         :confirm_terms_and_conditions

  has_many :occupational_fields
end


class OccupationalFieldSerializer
  include FastJsonapi::ObjectSerializer
  attributes :field

  has_many :candidates
end

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 25 апреля 2019

Проблема заключалась в том, что используемый сериализатор fast_jsonapi не может быть использован в качестве десериализатора, а сильные параметры Rail не могут обрабатывать ввод json.Он работает с гемом restful-jsonapi и измененными параметрами, как показано в примере с файлом readful restful-jsonapi.

...