无法将多对多关系传递给Create方法

时间:2019-04-26 22:50:57

标签: ruby-on-rails

自从我使用Rails以来可能已经很久了,但是我不知道为什么会这样(创建Task,然后使用prerequisites分配#prerequisite_ids=):

[3] pry(main)> task = Task.create(name:"do this last")                                                                                                                               
=> #<Task:0x00007fb0e2570860
 id: 7,
 name: "do this last",
  ...>
[4] pry(main)> task.prerequisite_ids=[5,6]                                                                                                                                           
=> [5, 6]
[5] pry(main)> task.prerequisites                                                                                                                                                    
=> [#<Task:0x00007fb0e2a82948
  id: 5,
  name: "Do this first",
  ...>
 #<Task:0x00007fb0e2a82600
  id: 6,
  name: "Do this next",
  ...>]

但这不是(将prerequisite_ids的数组传递给Task.create

[1] pry(main)> t = Task.create(name:"do this last", prerequisite_ids:[5,6])                                                                                                          
  Task Load (1.3ms)  SELECT "tasks".* FROM "tasks" WHERE "tasks"."id" IN ($1, $2)  [["id", 5], ["id", 6]]
   (0.3ms)  BEGIN
   (0.2ms)  ROLLBACK
=> #<Task:0x00007fb0e0e93d40 id: nil, name: "do this last", description: nil, created_at: nil, updated_at: nil, completed: false>
[2] pry(main)> t.errors                                                                                                                                                              
=> #<ActiveModel::Errors:0x00007fb0e2b18b00
 @base=#<Task:0x00007fb0e0e93d40 id: nil, name: "do this last", description: nil, created_at: nil, updated_at: nil, completed: false>,
 @details={:prerequisite_tasks=>[{:error=>:invalid}, {:error=>:invalid}]},
 @messages={:prerequisite_tasks=>["is invalid"]}>

<<运算符还可以添加prerequisitesta = Task.create(name:"do this last", prerequisites:[Task.find(5), Task.find(6)]同样不起作用,不起作用

我的模型和控制器(即使我猜想控制器实际上不在这里):

class Task < ApplicationRecord
  has_many :prerequisite_tasks, foreign_key: :do_second_id  
  has_many :prerequisites, through: :prerequisite_tasks, source: :do_first
end

class PrerequisiteTask < ApplicationRecord
  belongs_to :do_first, class_name: :Task
  belongs_to :do_second, class_name: :Task
end

class TasksController < ApplicationController
  def index
    render json: Task.all
  end

  def show
    task = Task.find(params[:id])
    render json: task
  end

  def create
    task = Task.create task_params
    render json: task, status: 201
  end
end

def task_params
  params.require(:task).permit :name, :description, :completed, prerequisite_ids: []
end

更新

我已通过此解决方法通过了测试:

  def create
    task = Task.create task_params.except(:prerequisite_ids)
    task.update prerequisite_ids: task_params[:prerequisite_ids]
    render json: task, status: 201
  end

进入测试显示创建的对象和返回的json都具有正确的prerequisite_ids。因此,它出现正常工作。

但是,当我尝试从Postman进行POST时,它不接受prerequisite_ids更新:

Started POST "/tasks?task[name]=Post%20from%20Postman&task[description]=Testing%20value%20types&task[completed]=true&task[prerequisite_ids]=[5,6]" for ::1 at 2019-04-26 23:57:12 +0000
Processing by TasksController#create as */*
  Parameters: {"task"=>{"name"=>"Post from Postman", "description"=>"Testing value types", "completed"=>"true", "prerequisite_ids"=>"[5,6]"}}
Unpermitted parameter: :prerequisite_ids
   (0.6ms)  BEGIN
  ↳ app/controllers/tasks_controller.rb:12
  Task Create (1.2ms)  INSERT INTO "tasks" ("name", "description", "created_at", "updated_at", "completed") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["name", "Post from Postman"], ["description", "Testing value types"], ["created_at", "2019-04-26 23:57:12.373180"], ["updated_at", "2019-04-26 23:57:12.373180"], ["completed", true]]
  ↳ app/controllers/tasks_controller.rb:12
   (1.1ms)  COMMIT
  ↳ app/controllers/tasks_controller.rb:12
Unpermitted parameter: :prerequisite_ids
   (0.6ms)  BEGIN
  ↳ app/controllers/tasks_controller.rb:13
  Task Load (0.5ms)  SELECT "tasks".* FROM "tasks" WHERE 1=0
  ↳ app/controllers/tasks_controller.rb:13
  Task Load (1.0ms)  SELECT "tasks".* FROM "tasks" INNER JOIN "prerequisite_tasks" ON "tasks"."id" = "prerequisite_tasks"."do_first_id" WHERE "prerequisite_tasks"."do_second_id" = $1  [["do_second_id", 15]]
  ↳ app/controllers/tasks_controller.rb:13
   (0.2ms)  COMMIT
  ↳ app/controllers/tasks_controller.rb:13
[active_model_serializers] Rendered TaskSerializer with ActiveModelSerializers::Adapter::Attributes (1.58ms)
Completed 201 Created in 55ms (Views: 7.9ms | ActiveRecord: 5.1ms)

返回的对象:

{
    "id": 16,
    "name": "Post from Postman",
    "description": "Testing value types",
    "completed": true,
    "prerequisite_ids": []
}

1 个答案:

答案 0 :(得分:1)

prerequisite_ids不是模型的属性,这就是为什么您不能将其传递到create方法中的原因。

相反,它是使用has_many :prerequisites创建关系时添加到类的帮助方法。

您可以在《 Rails指南》 Methods Added by has_manyActiveRecord::Associations::ClassMethods docs中阅读有关此功能的更多信息。