我试图“调试”我的TasksController的更新方法,以便它可以自动更新使用JSON API通过http发送的相关“标签”。我不确定执行此操作的正确方法是什么。
这是我的模特:
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模型来解决。没什么深奥的。
数据是使用Postman通过JSON API发送到模型的,我无法更改。这是邮递员在“正文”中的PATCH动作中发送的数据,如下所示:
{"data":
{ "type":"tasks",
"id":"2",
"attributes":{
"title":"Updated Task Title",
"tags": ["Urgent", "Home"]
}
}
}
我的ActiveModel序列化程序对于JSON API正常工作,因此,我相信我在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键值数组并以编程方式进行操作。过去,在将HTML表单用作前端时,我已经使用accepts_nested_attributes_for完成了这种事情。但这是我第一次处理JSON API。我怀疑这是一个比JSON API更通用的问题,因为序列化/反序列化可以正常工作。
很抱歉这个冗长的问题,但是我没有其他办法可以缩短它。