我有一个控制器(患者)将patient_id传递给另一个控制器(referral_requests)以用于构建推荐请求记录。我在尝试创建引用请求时遇到以下错误。我究竟做错了什么?我的referral_requests表包含user_id的整数列。
我有多个用枚举定义的用户类型。工作人员用户创建患者和转诊请求。
感谢您的帮助!
错误:
(0.1ms) rollback transaction
#<ActiveModel::Errors:0x007fe696696fc0 @base=#<ReferralRequest id: nil, content: nil, user_id: nil, created_at: nil, updated_at: nil, patient_id: 4, call_option_1: nil, call_option_2: nil, call_option_3: nil, call_option_1_status: nil, call_option_2_status: nil, call_option_3_status: nil, status: "created">, @messages={:user_id=>["can't be blank"]}, @details={:user_id=>[{:error=>:blank}]}>
患者控制器创建行动:
def create
@patient = current_user.patients.build(patient_params)
if @patient.save
flash[:success] = "Patient Created!"
redirect_to new_referral_request_path(patient_id: @patient.id)
else
Rails.logger.info(@patient.errors.inspect)
render 'patients/new'
end
referral_requests controller new和create actions,以及params:
def new
@patient = Patient.find(params[:patient_id])
@referral_request = current_user.referral_requests.build(patient: @patient) if signed_in?
end
def create
@referral_request = current_user.referral_requests.build(referral_request_params)
if @referral_request.save
flash[:success] = "Referral Request Created!"
redirect_to new_dispatch_path(referral_request_id: @referral_request.id)
else
Rails.logger.info(@referral_request.errors.inspect)
@feed_items = []
render 'static_pages/home'
end
end
private
def referral_request_params
params.require(:referral_request).permit(:content, :user_id, :patient_id, concern_ids: [], insurance_ids: [], race_ids: [], language_ids: [], gender_ids: [])
end
以下是模型关系:
require 'active_support/concern'
module StaffUser
extend ActiveSupport::Concern
included do
has_many :referral_requests, foreign_key: "user_id"
class ReferralRequest < ApplicationRecord
belongs_to :user, -> { where role: :staff }, class_name: 'User', foreign_key: 'user_id'
答案 0 :(得分:1)
“user_id”不应位于您允许的参数列表中。
编辑:
评论中的实际问题是他正在验证“user_id”而不是“user”的存在。通过关联创建记录时,id将不会在过程的后期填写,因此您只需检查相关项目的存在而不是ID:
validates :user, presence: true
答案 1 :(得分:1)
如果您要为患者创建推荐,您应该将其作为嵌套资源:
resources :patients do
resources: :referral_requests, shallow: true
end
由于创建此资源应该需要身份验证,因此您需要确保在之前的过滤器中处理该问题:
class ReferralRequestsController < ApplicationController
before_action :authenticate_user!
end
如果您正在推出自己的身份验证解决方案而不是使用Devise,请确保您有这样的方法:
class ApplicationController
private
def authenticate_user!
redirect_to new_session_path and return unless current_user
end
end
当我们创建资源备注时,我们没有从表单输入中获取user_id
(由会话提供)或患者ID(我们从路径段获取)。
class ReferralRequestsController < ApplicationController
before_action :authenticate_user!
before_action :set_patient, only: [:new, :create, :index]
# GET /patients/:patient_id/referral_requests/new
def new
@referral_request = @patient.referral_requests.new
end
# POST /patients/:patient_id/referral_requests
def create
@referral_request = @patient.referral_requests.new(referral_request_params) do |rr|
rr.user = current_user
end
if @referral_request.save
flash[:success] = "Referral Request Created!"
redirect_to new_dispatch_path(referral_request_id: @referral_request.id)
else
Rails.logger.info(@referral_request.errors.inspect)
@feed_items = []
render :new
end
end
private
def set_patient
@patient = Patient.find(params[:patient_id])
end
def referral_request_params
params.require(:referral_request)
.permit(:content,
concern_ids: [],
insurance_ids: [],
race_ids: [],
language_ids: [],
gender_ids: []
)
end
end
使用之前过滤器此处还将验证患者是否存在,因为Patient.find(params[:patient_id])
将ActiveRecord::RecordNotFound
举起。
一种很好的方法来处理应该使用用户输入创建记录的位置以及会话中的用户ID之类的其他值是传递块:
@referral_request = @patient.referral_requests.new(referral_request_params) do |rr|
rr.user = current_user
end
允许表单中的user_id
param使恶意用户可以通过使用Web检查器更改输入来传递任何用户ID!
通过传递数组在表单中创建正确的路径:
<%= form_for([@patient, @referral_request]) do |f| %>