NameError: неопределенная локальная переменная или метод clock_entry_params для #‹ClockEntriesController:0x00007f9e4347c208›

Я играю с Rails 6, и у меня проблема с моими сильными параметрами. Я создал CRUD Rails под названием ClockEntry с помощью rails g scaffold ClockEntry user:references purpose:string time_in:datetime time_out:datetime, и когда я нажимаю кнопку «Создать», я получаю

NameError: undefined local variable or method `clock_entry_params’ for #<ClockEntriesController:0x00007f9e4347c208>

Вот сгенерированная ниже миграция:

class CreateClockEntries < ActiveRecord::Migration[6.0]
  def change
    create_table :clock_entries do |t|
      t.references :user, null: false, foreign_key: true
      t.string :purpose
      t.datetime :time_in
      t.datetime :time_out

      t.timestamps
    end
    # add_index :clock_entries, %i[purpose time_in time_out]
    add_index :clock_entries, :purpose
    add_index :clock_entries, :time_in
    add_index :clock_entries, :time_out
  end
end

Вот схема, созданная ниже после запуска миграции:

create_table "clock_entries", force: :cascade do |t|
    t.bigint "user_id", null: false
    t.string "purpose"
    t.datetime "time_in"
    t.datetime "time_out"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["purpose"], name: "index_clock_entries_on_purpose"
    t.index ["time_in"], name: "index_clock_entries_on_time_in"
    t.index ["time_out"], name: "index_clock_entries_on_time_out"
    t.index ["user_id"], name: "index_clock_entries_on_user_id"
  end

Форма создания: обратите внимание, я написал другие функции, которые устанавливают time_in и time_out. Они находятся в моих частных методах внутри контроллера.

<%= simple_form_for(@clock_entry) do |f| %>
  <%= f.error_notification %>
  <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>

  <div class="form-inputs">
    <%#= f.association :user %>
    <%= f.input :purpose %>
    <%#= f.input :time_in %>
    <%#= f.input :time_out %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

Контроллер:

class ClockEntriesController < ApplicationController
  def new
    @clock_entry = ClockEntry.new 
  end

  def create
    @clock_entry = ClockEntry.new(clock_entry_params)

    respond_to do |format|
      if @clock_entry.save
        format.html { redirect_to @clock_entry, notice: 'Clock entry was successfully created.' }
        format.json { render :show, status: :created, location: @clock_entry }
      else
        format.html { render :new }
        format.json { render json: @clock_entry.errors, status: :unprocessable_entity }
      end
    end
  end

  private

  def set_time_in
    @clock_entry.time_in = Time.now
  end

  def set_time_out
    @clock_entry.time_in = Time.now
  end

  def clock_entry_params
    params.require(:clock_entry).permit(:user_id, :purpose, :time_in, :time_out)
  end
end

Любая помощь будет оценена. Примечание: я использую Postgres


person Afolabi Olaoluwa Akinwumi    schedule 21.09.2019    source источник
comment
где в вашем контроллере находится метод new, который инициализирует @clock_entry?   -  person Prakash Mishra    schedule 22.09.2019
comment
@PrakashMishra, я исправил это и опубликовал как ответ. Спасибо.   -  person Afolabi Olaoluwa Akinwumi    schedule 22.09.2019


Ответы (1)


Теперь я думаю, что знаю, где и почему я получил эту ошибку. Как я уже сказал, я написал другие функции в своих частных методах, которые устанавливают time_in и time_out, и вот как эти методы выглядят:

  def set_time_in
    @clock_entry.time_in = Time.now
  end

  def set_time_out
    @clock_entry.time_in = Time.now
  end

Прежде всего, функции бизнес-логики не должны находиться внутри контроллера. Чтобы ознакомиться с Business Logic, посетите https://www.reddit.com/r/rails/comments/77eesr/what_is_business_logic/

Как я решил эту проблему?

1. Все методы бизнес-логики перенесены в вашу модель. Итак, теперь у меня есть:

class ClockEntry < ApplicationRecord
  belongs_to :user

  validates :purpose, presence: true

  def set_time_in
    self.time_in = Time.now
  end

  def set_time_out
    self.time_in = Time.now
  end
end

2. Затем вы можете вызывать эти функции из вашего контроллера. Итак, у меня есть:

class ClockEntriesController < ApplicationController
  def create
    @clock_entry = current_user.clock_entries.new(clock_entry_params)
    @clock_entry.set_time_in # I am calling those logics here.

    respond_to do |format|
      if @clock_entry.save
        format.html { redirect_to @clock_entry, notice: 'Clock entry was successfully created.' }
        format.json { render :show, status: :created, location: @clock_entry }
      else
        format.html { render :new }
        format.json { render json: @clock_entry.errors, status: :unprocessable_entity }
      end
    end
  end

  private

  def set_clock_entry
    @clock_entry = ClockEntry.find(params[:id])
  end

  def clock_entry_params
    params.require(:clock_entry).permit(:user_id, :purpose, :time_in, :time_out)
  end

end

Так что это все, что я сделал, и это работает нормально. Я думаю, что иногда полезно прочитать контент о вашем стеке и освежить в памяти самые маленькие вещи, которые вы, должно быть, забыли. Я надеюсь, что это поможет кому-то. Gracias (Thanks).

person Afolabi Olaoluwa Akinwumi    schedule 22.09.2019