【问题标题】:Rails 3.2.x has_many, through (3 models) calls nil id before createRails 3.2.x has_many,通过(3 个模型)在创建之前调用 nil id
【发布时间】:2013-02-09 07:03:59
【问题描述】:

这是我正在处理的内容,但首先需要了解需要做什么的背景知识。有 3 种模型:患者 -- 预约 -- 程序

在这 3 个模型中,有两个视图程序 -- 患者

在这 2 个视图中,我想通过患者(显示)视图安排约会。这实质上将为视图中的患者创建一个新约会(特别是视图中的患者 ID)。

这是模型的代码

class Patient < ActiveRecord::Base
  attr_accessible :address1, :address2, :city, :comment, :email, :first_name, :init_date, :init_time, :last_name, :mobile, :notes, :phone, :state, :zip

  has_many :appointments, dependent: :destroy
  has_many :procedures, through: :appointments
class Procedure < ActiveRecord::Base
  attr_accessible :comment, :occurence, :procedure, :procedure_code, :procedure_price, :procedure_time, :visits
  has_many :appointments
  has_many :patients, through: :appointments
class Appointment < ActiveRecord::Base
  attr_accessible :appointment_date, :appointment_notes, :appointment_time, :procedure_id
  belongs_to :patient
  belongs_to :procedure

这是约会的控制器以及包含约会的 routes.rb (但只是那一行)

resources :appointments, only: [:create, :destroy, :edit, :update]
class AppointmentsController < ApplicationController
include PatientsHelper
before_filter :signed_in_user

def create
    @current_patient = @patient.id
    @appointment = @current_patient.appointments.build(params[:appointment])
    if @appointment.save
        flash[:success] = "Appointment scheduled!"
        redirect_to patient_path(@current_patient)
    else
        render 'create'
    end
end
module PatientsHelper

def current_patient=(patient)
    @current_patient = patient
end

def current_patient
    @current_patient
end

def current_patient?(patient)
    patient == current_patient
end
end

这就是设置,我在患者控制器中收到以下 rspec 错误。通过首先为@current_patient = Patient.first 定义一个ID,在控制台中测试了@appointment = @current_patient.appointments.build(params[:appointment])。这行得通,并且构建会按应有的方式进行。错误:

失败:

1) Appointment Pages appointment creation with invalid information should not create an appointment
 Failure/Error: expect { click_button "Schedule procedure" }.not_to change(Appointment,
 RuntimeError:
   Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
 # ./app/controllers/appointments_controller.rb:6:in `create'
 # (eval):2:in `click_button'
 # ./spec/requests/appointment_pages_spec.rb:17:in `block (5 levels) in <top (required)>'
 # ./spec/requests/appointment_pages_spec.rb:17:in `block (4 levels) in <top (required)>'

2) Appointment Pages appointment creation with invalid information error messages 
 Failure/Error: before { click_button "Schedule procedure" }
 RuntimeError:
   Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
 # ./app/controllers/appointments_controller.rb:6:in `create'
 # (eval):2:in `click_button'
 # ./spec/requests/appointment_pages_spec.rb:22:in `block (5 levels) in <top (required)>'

3) Appointment Pages appointment creation with valid information should create a micropost
 Failure/Error: expect { click_button "Schedule procedure" }.to change(Appointment,
 RuntimeError:
   Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
 # ./app/controllers/appointments_controller.rb:6:in `create'
 # (eval):2:in `click_button'
 # ./spec/requests/appointment_pages_spec.rb:36:in `block (5 levels) in <top (required)>'
 # ./spec/requests/appointment_pages_spec.rb:36:in `block (4 levels) in <top (required)>'

似乎我没有正确定义@current_patient = @patient.id... 或者更确切地说,当前的患者没有延续/通过预约表格。我需要在哪里定义当前患者以将该 ID 传递到 @current_patient.appointments.build 的表单创建方法?

【问题讨论】:

  • 你想用这行@current_patient = @patient.id做什么?你为@current_patient设置了一个ID号,现在@current_patient是一个数字,所以你不能调用appointments方法。另外,我认为您需要在未保存 @appointment 时呈现新动作,而不是创建动作。
  • 因为这是通过患者视图页面我想使用 patient.appointments.build 安排新约会,不想通过新操作创建它。在我的浏览器中,表单通过 app.dev/patients/3 显示(其中 3 是当前患者视图)。这是约会安排应该发生的地方。我的约会模型,也许它的控制器不知道当前的病人。这就是我认为的问题所在。不确定如何编写适当的代码来定义“current_patient in view”。我怀疑它类似于控制台@current_patient = Patient.first
  • 好的,如果您想获取当前患者的 ID 为 3,就像在上面的链接中一样,试试这个:@current_patient = Patient.where(id: params[:id]) 在您的创建操作中,params[:id] 是您当前的患者 ID患者视图。在控制台中,您将@current_patient 设置为一个患者对象,否则在您的创建操作中,您将其设置为一个数字,所以它只是在控制台中工作,
  • 将其插入并...现在它创建了一个新错误.. NoMethodError: undefined method 'appointments' for []:ActiveRecord::Relation # ./app/controllers/appointments_controller.rb:8:in 'create' 不确定关联在哪里中断,但似乎找到了患者(由患者 I如果我正确理解您的代码,则意味着所有患者属性,而不仅仅是 id。
  • 哦,对不起,我忘了Patient.where(id: params[:id])返回一个对象数组,添加first方法来获取当前患者,所以它应该是Patient.where(id: params[:id]).first:D

标签: ruby-on-rails ruby-on-rails-3.2 rspec2 nested-attributes has-many-through


【解决方案1】:

不完全是我想要的,但解决了这个问题。

使用以下内容可以得到相应的保存。 仍然无法找出我无法从 URL 中提取患者的原因——例如 app.dev/patients/2——其中患者信息正在提取 id 2...但现在我能够使用我怀疑是一种相当粗糙的方法来保存约会。

  1. 在表单中,我添加了一个隐藏字段,用于提取适当的患者 ID
  2. 在 Appointments 控制器中,添加到 attr_accessible :patient_id
  3. 在约会控制器中

    def create
    @appointment = Appointment.new(params[:appointment])
    @current_patient = @appointment.patient_id
    if @appointment.save
        flash[:success] = "Appointment scheduled!"
        redirect_to patient_path(@current_patient)
    else
        render 'patients/show'
    end
    end
    

render 'patients/show' 仍然损坏,但会将其留给另一个线程。谢谢大家的帮助和指导。同样,我怀疑渲染调用与当前困扰我从约会控制器模型直接访问 current_patient 的问题有关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2012-06-27
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多