I am getting an error "undefined method " when I try to build a nested resource on action 'new' in rails 4.2
Here's my routes:
devise_for :medics
resources :patients, shallow: true do
resources :consultations do
resources :prescriptions
end
end
I have Devise for system logon, and rather than use "User" to the model name, I use "Medic" in order to use the registry to devise to create a type of medical profile with a new fields like name, phone, etc. (I don't know if here's the problem)...
Patients controller:
class PatientsController < ApplicationController
before_action :set_medic
def new
@patient = @medic.patients.new
end
def create
@patient = @medic.patients.new(patient_params)
end
def set_medic
@medic = Medic.find_by_id(params[:medic_id])
end
Model:
class Medic < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :patients, :dependent => :destroy
end
class Patient < ActiveRecord::Base
belongs_to :medic, :foreign_key => :medic_id, :dependent => :destroy
has_many :consultations
accepts_nested_attributes_for :consultations
end
View:
<%= link_to 'New Patient', new_patient_path(@medic) %>
rake routes:
new_patient GET /patients/new(.:format) patients#new
Error:
undefined method `patients' for nil:NilClass
in this line: @patient = @medic.patients.new
Any idea? thaks in advance
The problem is very simple.
You're calling the following on each request:
def set_medic
@medic = Medic.find_by_id(params[:medic_id])
end
The problem is that you're not passing medic_id
through your routes:
devise_for :medics
resources :patients, shallow: true do #-> no medic_id here
resources :consultations do #-> or here
resources :prescriptions #-> or here
end
end
Therefore, what happens is that you're trying to find a Medic
without any id
, hence the NilClass
error.
You're getting confused with the nested resources
directive in Rails routes:
#DON'T use this - it's just an example
#config/routes.rb
resources :medics do
resources :patients #-> url.com/medics/:medic_id/patients/:id
end
As you're using Devise
, I think you'd be able to get away with scoping your calls around the current_medic
helper (which is what I presume you're doing)...
-
Fix
#app/controllers/patients_controller.rb
class PatientsController < ApplicationController
def new
@patient = current_medic.patients.new
end
def create
@patient = current_medic.patients.new(patient_params)
end
end
This way, you'll be able to use (as you're using current_medic
):
<%= link_to "New", new_patient_path %>