¿Por qué el método post/crear falla con error
Soy nuevo en RoR. Quería probar si mi próxima aplicación web debería estar basada en RoR. Comenzó a seguir este rastro: https://guides.rubyonrails.org/getting_started.html. Trabajé como un encanto en el principio, pero no puedo conseguir la cosa del darn para crear nuevos discos. Cualquier pista de lo que me falta es apreciada.
El error que estoy recibiendo es este:
D, [2020-12-18T09:59:56.917197 #132399] DEBUG -- : Createevent
F, [2020-12-18T09:59:56.917893 #132399] FATAL -- :
ActionController::ParameterMissing (param is missing or the value is empty: Event):
app/controllers/event_controller.rb:33:in `event_params'
Mi pudrición se ve así:
Rails.application.routes.draw do
post 'event/new', to: 'event#create'
resources :event
end
(Estoy desconcertado por la necesidad de especificar el POST arriba, pero sin él la creación nunca se dispara. ).
El controlador de eventos se ve así:
class EventController < ApplicationController
def index
@events = Event.all
end
def show
@event = Event.find(params[:id])
end
def new
logger = Rails.logger
logger.info 'NewEvent'
@event = Event.new
end
def create
logger = Rails.logger
logger.debug 'Createevent'
@event = Event.new(event_params)
logger.debug 'Eventcreated'
if @event.save
redirect_to event_path
else
render :new
end
end
private
def event_params
params.require(:Event).permit(:EventName, :Description, :EventStart, :EventEnd, :Maxparticipants, :Waitlist )
end
end
El índice y el espectáculo funciona bien.
El nuevo.html.erb se ve así:
New Event
dsfsdfds
<%= form_with model: @Event do |form| %>
<%= form.label :eventname %>
<%= form.text_field :EventName %>
<%= @event.errors.full_messages_for(:EventName).each do |message| %>
<%= message %>
<% end %>
<%= form.label :Description %>
<%= form.text_field :Description %>
<%= @event.errors.full_messages_for(:description).each do |message| %>
<%= message %>
<% end %>
<%= form.label :EventStart %>
<%= form.text_field :EventStart %>
<%= @event.errors.full_messages_for(:eventstart).each do |message| %>
<%= message %>
<% end %>
<%= form.label :Eventend %>
<%= form.text_field :Eventend %>
<%= @event.errors.full_messages_for(:eventend).each do |message| %>
<%= message %>
<% end %>
<%= form.label :Maxparticipants %>
<%= form.text_field :Maxparticipants %>
<%= @event.errors.full_messages_for(:Maxparticipants).each do |message| %>
<%= message %>
<% end %>
<%= form.label :Waitlist %>
<%= form.text_field :Waitlist %>
<%= @event.errors.full_messages_for(:waitlist).each do |message| %>
<%= message %>
<% end %>
<%= form.submit %>
<%= submit_tag "Create" %>
<% end %>
Rutas:
Prefix Verb URI Pattern Controller#Action
event_new POST /event/new(.:format) event#create
event_index GET /event(.:format) event#index
POST /event(.:format) event#create
new_event GET /event/new(.:format) event#new
edit_event GET /event/:id/edit(.:format) event#edit
event GET /event/:id(.:format) event#show
PATCH /event/:id(.:format) event#update
PUT /event/:id(.:format) event#update
DELETE /event/:id(.:format) event#destroy
Cosas creadas usando:
bin/rails generate model Event EventName:string Description:string EventStart:datetime EventEnd:datetime Maxparticipants:integer WaitList:integer
bin/rails generate controller Event index
Versión:
About your application's environment
Rails version 6.0.3.4
Ruby version ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
RubyGems version 3.1.4
Rack version 2.2.3
Gracias a Hackman & nathanvda por aclarar. Lo arruiné todo y empecé y finalmente conseguí que funcionara. Todavía demasiado leña y magia negra para mi gusto. La parte del mensaje de error me desconcertó durante tres horas consecutivas.
Como dije, seguí la guía y por lo tanto terminé usando (en nuevo)
<%= form_with model: @event do |form| %>
<% if @event.errors.any? %>
Errors
<% @event.errors.full_messages.each do |message| %>
- <%= message %>
<% end %>
<% end %>
...
Que funciona (bueno, algo así). El registro se salva si está bien, las reglas de validación se despide
class Event < ApplicationRecord
validates :eventname, presence: true
validates :description, presence: true, length: { minimum: 20 }
end
y si no se viola ningún registro se escribe en la base de datos, pero tampoco hay mensajes de error. Nil. Nada. Después de correr por internet terminé cambiando a
<%= form_for @event do |form| %>
y luego el reporte de errores funciona. Sólo problema con esta solución es que el uso de form_for se desalienta ya que se está haciendo obsoleto.
La versión final terminó siendo:
<%= form_with model: @event, local: true do |form| %>
Que hace el truco.
El siguiente paso en mi evaluación será el uso de claves naturales ya que el uso de llaves surrogadas no es una opción para algunas de las estructuras de datos necesarias en este proyecto. (Durante mi caceo alrededor tengo la impresión de que las llaves naturales son una especie de diente dolorido en RoR, pero el tiempo se mostrará.
Pregunta hecha hace 3 años, 4 meses, 27 días - Por syntaxsavvy
4 Respuestas:
-
Para empezar, sus recursos en las rutas deben ser pluralizados. Así que...
resources :event
debería serresources :events
También el nombre del controlador debe ser pluralizado. Así que...
EventController
se convertiría enEventsController
.Ahora las rutas necesarias deben funcionar bien y usted puede deshacerse del POST especificado en sus rutas.rb
Ahora dentro de su controlador tiene el método event_params. Allí se prefiere para minúscula / snake_case los nombres como este:
def event_params params.require(:event).permit(:event_name #etc) end
Si sus nombres de columnas en DB son EventName etc, le aconsejaría cambiar su nombre.
Lo último: En tu forma tienes
@Event
con mayúscula mientras que en el controlador#nueva acción usted definió@event
con minúscula. Use minúsculas por todas partes.Respondida el Dec 18, 2020 a las 12:40 - por logiclinguist
Votos positivos: 0 | Votos negativos: 0 -
Así que si hubieras comenzado como sigue:
bin/rails generate model Event event_name:string description:string event\-start:datetime event_end:datetime max_participants:integer wait_list:integer bin/rails generate controller events index
Entonces el código generado funcionaría mucho mejor.
Algunos consejos para aclarar:
- en ruby sólo escribimos clases con una capital, para variables que utilizamos caso de serpiente (todo minúscula y palabras conectadas con subrayados). Por lo tanto, por extensión cuando se genera un modelo todos los atributos deben ser caso de serpiente
- un controlador en general utiliza la forma plural, ya que "controla" todos los eventos (no sólo uno).
Respondida el Dec 18, 2020 a las 12:48 - por compilercaptain7dab
Votos positivos: 0 | Votos negativos: 0 -
El error que estás experimentando se debe a que el método
require
en el métodoevent_params
del controlador está esperando que se pase el parámetroEvent
en mayúsculas, pero en realidad los parámetros que se envían a través del formulario generalmente están en minúsculas.Debes cambiar
params.require(:Event)
porparams.require(:event)
para que pueda acceder correctamente a los parámetros enviados a través del formulario.Además, parece que estás teniendo problemas con la visualización de los errores en el formulario. En lugar de usar
@event.errors.full_messages_for(:Attribute)
, puedes usar@event.errors.full_messages_for(:attribute).each
para mostrar los mensajes de error asociados con cada atributo que tiene errores en el formulario.Por último, asegúrate de que estás utilizando las convenciones de Rails para los nombres de los modelos y atributos, ya que Rails espera ciertas convenciones para las convenciones de nombres de los modelos y atributos.
Realiza estos ajustes y vuelve a probar el proceso de creación de eventos. Si sigues experimentando problemas, no dudes en volver a preguntar. ¡Buena suerte con tu aplicación en Rails!
Respondida el Dec 19, 2020 a las 12:42 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El error que estás encontrando se debe a que el parámetro
Event
no está presente en los parámetros de la solicitud. El métodoevent_params
en el controlador Events espera un hash con la claveEvent
, que contiene los parámetros del evento que se está creando.Para resolver este problema, puedes agregar el siguiente código a tu vista
new.html.erb
:erb <%= form_with(model: @event) do |form| %>
El resto de tu código de formulario
<% end %>Esto agregará el parámetro
Event
a los parámetros de la solicitud, que luego se pueden usar en el métodoevent_params
del controlador.También puedes intentar cambiar la ruta
post 'event/new'
apost 'event'
para que coincida con el nombre del controlador.Aquí hay un ejemplo de cómo debería verse tu controlador Events después de estos cambios:
ruby class EventController < ApplicationController def index @events = Event.all end def show @event = Event.find(params[:id]) end def new logger = Rails.logger logger.info 'NewEvent' @event = Event.new end def create logger = Rails.logger logger.debug 'Createevent' @event = Event.new(event_params) logger.debug 'Eventcreated' if @event.save redirect_to event_path else render :new end end private def event_params params.require(:event).permit(:eventname, :description, :eventstart, :eventend, :maxparticipants, :waitlist) end end
Ten en cuenta que el nombre de los parámetros en
event_params
debe coincidir con los nombres de los campos de tu modelo Event.Respondida el Dec 19, 2020 a las 12:46 - por Gemini
Votos positivos: 0 | Votos negativos: 0