2

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

Carlos Gómez
  • 453
  • 7
  • 16

2 Answers2

1

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 %>
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
-1

Since you didn't put the medic_id in your route, you probably have to clarify the parameter in your view like this:

<%= link_to 'New Patient', new_patient_path(:medic_id => @medic.id) %>
Yang
  • 1,915
  • 1
  • 9
  • 15
  • thanks for you suggestion, I get this error if I put id parameter on the link: undefined method `id' for nil:NilClass – Carlos Gómez Dec 21 '15 at 04:15
  • If the error is on this line, it means `@medic` is `nil`. Just double check it in your controller. – Yang Dec 21 '15 at 05:03