¿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 ser resources :events

    También el nombre del controlador debe ser pluralizado. Así que... EventController se convertiría en EventsController.

    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étodo event_params del controlador está esperando que se pase el parámetro Event 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) por params.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étodo event_params en el controlador Events espera un hash con la clave Event, 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étodo event_params del controlador.

    También puedes intentar cambiar la ruta post 'event/new' a post '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