Не могу получить данные из формы. Ruby on Rails

Рейтинг: 0Ответов: 1Опубликовано: 09.01.2023

Контроллер:

class CuratorController < ApplicationController
  def index
    @studs = Stud.all
  end

  def show
    @stud = Stud.find(params[:id])
  end

  def new
    @studs = Stud.new
  end

  def create
    @stud = Stud.new(stud_params)
    @stud.save
    redirect_to new_curators_path

  end

  private
    def stud_params
      params.permit(:fio, :test)
    end
end

Страница на которой пользователь вводит данные:

<h1>New Student</h1>

<%= form_with model: @stud do |form| %>
  <div>
    <%= form.label :text %><br>
    <%= form.text_field :fio %>
  </div>

  <div>
    <%= form.label :integer %><br>
    <%= form.text_field :test %>
  </div>

  <div>
    <%= form.submit type: "submit", name:"action" %>
  </div>
<% end %>

Пишет, что param отсутствует или значение пустое: stud Не могу понять почему, в консоли, где запущен сервер вот это:

ActionController::ParameterMissing (param is missing or the value is empty: stud):

app/controllers/curator_controller.rb:25:in `stud_params'
app/controllers/curator_controller.rb:15:in `create'
Started POST "/curator" for ::1 at 2023-01-09 02:45:58 +0300
Processing by CuratorController#create as HTML
  Parameters: {"authenticity_token"=>"[FILTERED]", "text"=>"Аметист", "integer"=>"76"}
Completed 400 Bad Request in 4ms (Allocations: 1476)



ActionController::ParameterMissing (param is missing or the value is empty: stud):

app/controllers/curator_controller.rb:23:in `stud_params'
app/controllers/curator_controller.rb:15:in `create'

Добавил код routes. Почему-то resources не создаёт сам Post, поэтому написал его отдельно, вот код

Rails.application.routes.draw do

  root "curator#index"
  resources :curator
  post 'curator/new', to: 'curator#create'
end

Обновил код контроллера и страницы html Сейчас ругается на stud.save выдаёт: undefined method `integer' for #<Stud id: nil, fio: "Ametist", test: 12412412, created_at: nil, updated_at: nil> Когда ввожу соответственно Ametist и 12412412 P.S. Спасибо большое за то, что уже видит данные, которые вводит, это очень большой прогресс для меня!

Ответы

▲ 0

Когда вы пермитите параметры таким образом params.require(:stud).permit(fio: :text, :integer), предполагается, что в параметрах должен быть хэш вида {stud: { fio: { text: 'Some text' }, integer: 5 } }

Форма же ваша, во-первых, ничего не знает о ключе fio и пришлёт просто { text: 'Some text', integer: 5 } (что мы и видим в логах). Во-вторых, в форме у вас form_with model: @students, а переменная @students не определена в контроллере, в нём я вижу только @stud = Stud.new. Так что для начала замените переменную в форме.

Что делать с ключом fio - я не знаю, потому как в вопросе нет описания этой части, и непонятно, какие поля есть в модели Stud.

Вместо render "/curator/new" должно быть redirect_to new_curators_path, я полагаю.

UPD:

Про роуты. Чтобы ресурсный роут работал верно, нужно использовать множественное число resources :curators, тогда все крудовые роуты сгенерятся автомагически. В рельсах очень много построено на соглашениях, convention over configuration.

Следующий момент - контроллеры принято именовать по той сущности, с которой они работают, и тоже во множественном числе (это одно из условий автомагической работы роутов). У вас же CuratorController работает с сущностью Stud, гораздо удобнее было бы назвать его StudsController (или может быть StudentsController - если это сокращение, то лучше его избежать, чтобы проще было читать код)

Не совсем поняла причину, по которой вам пришлось переименовать переменную в new, скорее всего она была связана с проблемой в роутах и ошибка была немного не там. Смотрите, в чём её смысл вообще - вы используете её в форме, и это позволяет отображать валидационные ошибки, строить форму для редактирования и группировать параметры из формы под отдельным ключом

Позволила себе накидать код, как он должен в итоге выглядеть, чтобы всё работало верно. Обратите внимание на if-else в контроллере - при успешном сохранении мы редиректим на страничку сущности, а при ошибках валидации снова показываем форму с ними

# app/controllers/studs_controller.rb
class StudsController < ApplicationController
  def index
    @studs = Stud.all
  end

  def show
    @stud = Stud.find(params[:id])
  end

  def new
    @stud = Stud.new
  end

  def create
    @stud = Stud.new(stud_params)

    if @stud.save
      redirect_to stud_path(@stud)
    else
      render :new
    end
  end

  private

  def stud_params
    params.require(:stud).permit(:fio, :test)
  end
end

# app/views/studs/new.html.erb
<%= form_with model: @stud do |form| %>
  <div>
    <%= form.label :fio %><br>
    <%= form.text_field :fio %>
  </div>

  <div>
    <%= form.label :test %><br>
    <%= form.number_field :test %>
  </div>

  <div>
    <%= form.submit "Создать" %>
  </div>
<% end %>

# config/routes.rb
Rails.application.routes.draw do
  root "studs#index"
  resources :studs
end