Как обновить связанные записи в рельсах - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь «отладить» метод обновления моего TasksController, чтобы он мог автоматически обновлять связанные «теги», которые отправляются через http с помощью JSON API.Я не уверен, каков правильный способ сделать это.

Вот мои модели:

class Task < ApplicationRecord
  has_many :task_tags
  has_many :tags, through: :task_tags
  validates :title, presence: true
  validates :title, uniqueness: true
end

class Tag < ApplicationRecord
  has_many :task_tags
  has_many :tasks, through: :task_tags
  validates :title, presence: true
  validates :title, uniqueness: true
end

class TaskTag < ApplicationRecord
  belongs_to :task
  belongs_to :tag
  validates :task_id, presence: true
  validates :tag_id, presence: true
end

Таким образом, модель задач и модель тегов связаны друг с другом во многих-много отношения, которые решаются с помощью модели TaskTag.Ничего глубокого.

Данные отправляются в модель через JSON API с помощью Postman, который я не могу изменить.Вот данные, которые отправляются с помощью действия PATCH Почтальона в «теле», как показано ниже:

{"data":
    {   "type":"tasks",
        "id":"2",

        "attributes":{
            "title":"Updated Task Title",
            "tags": ["Urgent", "Home"]
        }
    }
}

Мой сериализатор ActiveModel работает правильно для JSON API, и поэтому я считаю, что получаюправильные данные в действии «update» моего TasksController, показанном ниже:

class Api::V1::TasksController < ApplicationController
   ...
  def update
    task = Task.find(params[:id])
    byebug
    if task.update_attributes(task_params)
      render json: task, status: 201
    else
      render json: { errors: task.errors.full_messages }, status: 422
    end
  end
  ...
  private

  def task_params
    ActiveModelSerializers::Deserialization.jsonapi_parse(params)
  end
end

См. оператор «byebug» в моем методе обновления?Программа там корректно ломается.В приглашении byebug в терминале я набрал 'task_params', чтобы увидеть, что он возвращает.Вот вывод:

[21, 30] in /Users/bharat/scout/todo_api_app/app/controllers/api/v1/tasks_controller.rb
   21:   end
   22: 
   23:   def update
   24:     task = Task.find(params[:id])
   25:     byebug
=> 26:     if task.update_attributes(task_params)
   27:       render json: task, status: 201
   28:     else
   29:       render json: { errors: task.errors.full_messages }, status: 422
   30:     end
(byebug) task_params
{:title=>"Updated Task Title", :tags=>["Urgent", "Home"], :id=>"2"}
(byebug) 

Таким образом, все сводится к получению хэша с ключом:: tags, который имеет массив значений заголовков тегов.Мой вопрос: что такое Rails способ автоматического создания тегов?Я всегда могу извлечь массив значений ключа: tags и программно сделать это.В прошлом я делал подобные вещи, используя accepts_nested_attributes_for при использовании форм HTML в качестве внешнего интерфейса.Но это первый раз, когда я имею дело с JSON API.Я подозреваю, что это более общий вопрос, чем JSON API, поскольку сериализация / десериализация работает правильно.

Извините за длинный вопрос, но я не мог придумать иного способа сократить его..

...