如何从React做两个相关Rails模型的POST请求?

时间:2017-05-05 00:26:45

标签: ruby-on-rails api reactjs associations

我有一个rails-api应用程序作为后端,并作为前端的反应应用程序。

在rails内部,我有一个Schedule模型,has_many workersWorker模型belongs_to schedule。当用户创建新计划时,他们可以选择date并选择工作人员的name。我的斗争是,我想不出办法传递工人的schedule_id

这就是我所拥有的:

我有两种获取方法;每个发送数据/向指定的API发出POST请求。

function postSchedule(date, cb) {
  return fetch(`api/schedules`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      date: date,
      user_id: 1 
    })
  }).then((response) => response.json())
    .then(cb); //cb setStates schedules state in main react app
};

function postWorker(workerName, cb) {
  return fetch('api/workers', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      worker: workerName,
      schedule_id: //how do I know schedule_id?
    })
  }).then((response) => response.json())
    .then(cb); //cb setStates workers state in main react app
}

Rails模型:

//schedule.rb
class Schedule < ApplicationRecord
  belongs_to :user
  has_many :workers
end

//worker.rb
class Worker < ApplicationRecord
  belongs_to :schedule, optional: true
end

Rails控制器:

  //schedules_controller.rb
  def create
    @schedule = Schedule.new(schedule_params)
    if @schedule.save
      render json: @schedule
    else
      render json: @schedule, status: :unprocessable_entity
    end
  end

  //workers_controller.rb
  def create
    @worker = Worker.new(worker_params) #params.permit(:name, :phone, :schedule_id)
    if @worker.save
      render json: @worker
    else
      render json: @worker, status: :unprocessable_entity
    end
  end

表单看起来像这样。用户将同时创建新的计划新员工。 create new schedule form

如果用户正在创建新的时间表,显然此时间表尚未存在于DB中,因此在提交之前我不会知道此时间表的ID。当我创建一个新工人时,它需要schedule_id。我怎样才能让Rails知道这个worker的schedule_id是什么?

为新创建的工作人员分配新创建的时间表有什么好策略?

2 个答案:

答案 0 :(得分:0)

我的朋友昨晚给了我一个暗示,我得到了它的工作。他说除非我提交,接受并返回对新schedule_id的回复,否则无法获取schedule_id信息。

所以为了解决我的问题,我确实要提出两个请求。首先,我需要发出一个请求来计划rails中的模型,等待rails接受它,然后等待rails返回response。响应内部是schedule_id。我.thenschedule_id分配了我从rails获得的计划ID。

有点乱,我需要清理它。但这对我有用:

Client.postSchedule(this.state.date, (schedule) => {
  this.setState({schedules: this.state.schedules.concat([schedule])})
}).then(() => Client.postWorker(this.state.worker, this.state.phone, this.state.schedules[this.state.schedules.length - 1].id, (worker) => {
    this.setState({workers: this.state.workers.concat([worker])})
  })
)

this.state.schedules[this.state.schedules.length - 1].id有点混淆。它真正做的是,我有一系列的日程安排,我存储我的日程安排对象。我只是让React知道在数组中获取最后的时间表(这将是最新的时间表),并在scheduleles数组中给我最后一个schedule对象的ID。

简而言之,(sends request to schedule) -> (wait response back from Rails that contains the schedule_id that I need) -> (use that schedule_id information to send another request)。解决方案是检查then

答案 1 :(得分:0)

在这里,您可以在Schedule模型中使用rails accepts_nested_attributes_for。

在“计划模型”中添加以下行

 accepts_nested_attributes_for :workers

然后在SchedulesController中,更新schedule_params方法。

def schedule_params

   params.require(:schedule).permit(:user_id, :date, workers_attributes: [:id, :name, :phone])

end

在你的反应中

function postSchedule(date, cb) {
  return fetch(`api/schedules`, {
   method: 'POST',
   headers: {
    'Content-Type': 'application/json',
   },
   body: JSON.stringify({
    date: date,
    user_id: 1,
    workers_attributes: [
     {
      name: worker_name,
      phone: phone
     }
    ]

  })

 }).then((response) => response.json())

 .then(cb); //cb setStates schedules state in main react app  
};

现在只有一个请求可以满足您创建计划和工作人员的目的。

供参考 http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html