Не могу найти <Model>без ID - рельсы 5 - PullRequest
1 голос
/ 03 февраля 2020

У меня есть две модели: RegisterHour и Employee

Это моя модель RegisterHour :

class RegisterHour < ApplicationRecord
   belongs_to :employee, class_name: 'Employee', foreign_key: 'employee_id'
end

И эта моя модель: Employee

class Employee < ApplicationRecord
   has_many :register_hours, dependent: :destroy
end

Отображение моих маршрутов для этого случая

resources :employees do
   resources :register_hours
end

Это мой контроллер:

class RegisterHoursController < ApplicationController
  before_action :set_employee
  before_action :set_hour, :set_employee_hour

  def index
   json_response(@employee.register_hours)
  end

  private
   def set_hour
     @register_hour = RegisterHour.find(params[:id])
   end

   def set_employee
     @employee = Employee.find(params[:employee_id])
   end

   def set_employee_hour
     @register_hour = @employee.register_hours.find_by(id: params[:id]) if @employee
   end


   def hour_params
    params.permit(:status)
   end
 end

Итак, когда я запускаю маршрут: http://my_url_in_local / employee / 1 / register_hours Я получил эту ошибку:

{
  "message": "Couldn't find RegisterHour without an ID"
}

Я так запутался, потому что у меня есть другой контроллер с той же структурой для управления администраторами и сотрудниками, и он работает, но этот контроллер этого не делает.

Я новичок ie с рельсами - это мое замешательство, если кто-нибудь может помочь мне понять, что я делаю неправильно, я буду очень счастлив:)

Спасибо !!

Ответы [ 2 ]

2 голосов
/ 03 февраля 2020

Если посмотреть, как определяются ваши маршруты, у вас есть что-то вроде этого:

employee_register_hours GET    /employees/:employee_id/register_hours(.:format)     register_hours#index
                        POST   /employees/:employee_id/register_hours(.:format)     register_hours#create
 employee_register_hour GET    /employees/:employee_id/register_hours/:id(.:format) register_hours#show
                        PATCH  /employees/:employee_id/register_hours/:id(.:format) register_hours#update
                        PUT    /employees/:employee_id/register_hours/:id(.:format) register_hours#update
                        DELETE /employees/:employee_id/register_hours/:id(.:format) register_hours#destroy
              employees GET    /employees(.:format)                                 employees#index
                        POST   /employees(.:format)                                 employees#create
               employee GET    /employees/:id(.:format)                             employees#show
                        PATCH  /employees/:id(.:format)                             employees#update
                        PUT    /employees/:id(.:format)                             employees#update
                        DELETE /employees/:id(.:format)                             employees#destroy

Если вы видите там, URI, маршрутизирующий действие index в RegisterHoursController, только указывает, что employee_id в параметрах ожидается. Но в вашем приватном set_hour методе вы ожидаете, что параметры содержат id, соответствующий существующей записи RecordHour в вашей базе данных:

RegisterHour.find(params[:id])

Там, где происходит ваша ошибка. Поскольку вы не отправляете этот идентификатор, команда find вызывает ошибку ActiveRecord::RecordNotFound.

У вас есть простое решение - удалить этот метод и все, что с ним связано. Итак, ваш RegisterHoursController может оказаться гораздо более простым:

class RegisterHoursController < ApplicationController
  def index
    @employee = Employee.find(params[:employee_id])
    json_response(@employee.register_hours)
  end

  private

  def hour_params
    params.permit(:status)
  end
end

Почему? Поскольку вы не получаете идентификатор RegisterHour, то set_hour не требуется, таким образом set_employee_hour также становится ненужным, потому что @employee.register_hours.find_by(id: params[:id]) всегда будет возвращать nil.

Удаление этого, в итоге вы получите set_employee, который можно просто переместить в действие, к которому он принадлежит, что позволит вам удалить обратный вызов before_action.

Обратите внимание: если вы используете только действие index в RegisterHoursController, тогда вы можно избежать генерации всех других ненужных маршрутов:

resources :employees do
  resources :register_hours, only: :index
end
0 голосов
/ 03 февраля 2020

Причина - before_action :set_hour, :set_employee_hour. Поскольку ваш метод индекса не содержит :id параметров от маршрутов.

Вы можете исправить это с помощью.

От:

before_action :set_hour, :set_employee_hour

До:

before_action :set_employee_hour
before_action :set_hour, except: [:index]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...