Не могу получить данные из формы. Ruby on Rails
Контроллер:
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. Спасибо большое за то, что уже видит данные, которые вводит, это очень большой прогресс для меня!
Ответы (1 шт):
Когда вы пермитите параметры таким образом 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