¿Cómo obtengo un controlador de mesa para mostrar una asociación de clave extranjera? [Rubymine 2020.2.3, Ruby.2.7.2p137, gem 3.1.2]
Estoy cerca del plazo para un proyecto universitario (3 semanas) y he encontrado varios problemas. Al ser un curso de proyecto, no siempre puedo referirme a mi tutor.
Anteriormente He hecho una pregunta que ha proporcionado soluciones para una mesa que no tenía una llave extranjera, gracias a la gente amable en este sitio, finalmente se resuelve. Una cuestión más larga es conseguir mesa para trabajar con una llave extranjera, una de estas tablas nunca mostrará un único registro de datos en el índice.
Este es el método Crear del controlador de mesa 'Shipment' donde trato de crear una asociación al 'Courier' al que pertenece el Shipment_to y el Courier tiene_muy de. Las siguientes líneas son según las instrucciones del documento de mi curso:
@cour_id=params[:shipment][:courier_id]
@courier=Courier.find(@cour_id)
@shipment=Shipment.new(params.require(:shipment).permit(:tracking_number, :shipment_date))
@shipment.courier<< @courier
@shipment.save
redirect_to shipment_path(@shipment)
@shipment=Shipment.new(shipment_new_path)
if @shipment.save
redirect_to(:controller=>'shipment' ,:action=>'index')
else
render('new')
end
end
Las asociaciones parecen ser necesarias porque una de las formas en el envío/new.erb.html es una caída de un conjunto de registros de Courier de una de sus columnas de mesa. Lo que parece mostrar desde esa forma dentro de esa página.
El tema que encuentro es en la línea '@shipment.courier Identificado @courier', el 'traducido' se trata como un método indefinido para nil:NilClass. He probado variaciones de esta línea de código (@shipment.couriers..., @shipment.courier.id...), pero no parece marcar la diferencia.
Sospecho que un problema más apremiante está en juego desde esta tabla en particular, noté que incluso desde el fondo, la mesa no parecería guardar nuevos registros. Aunque no hay nada particularmente diferente de esta tabla en comparación con otros. Inicialmente he atribuido que es incapaz de pasar datos debido a una desalineación entre las asociaciones de mesa, ahora lo interpreto como una cuestión de no poder funcionar sin estar adecuadamente conectado con el id de la tabla Courier.
La pregunta es, ¿cómo puedo hacer que las asociaciones funcionen?
Pregunta hecha hace 3 años, 4 meses, 24 días - Por compilercaptain
3 Respuestas:
-
Esto es realmente sólo un recurso estándar de nido de la época que estás describiendo. Realmente no sé qué hacer del conjunto de código en su pregunta - pero la forma de Rails de hacer esto sería:
resources :couriers do resources :shipments, only: [:index, :new, :create] end
class ShipmentsController < ApplicationController # use callbacks to avoid repitition before_action :set_courier, only: [:new, :create, :index] # GET /couriers/1/shipments def index @shipments = @courier.shipments end # GET /couriers/1/shipments/new def new @shipment = @courier.shipments.new end # POST /couriers/1/shipments def create @shipment = @courier.shipments.new(shipment_params) if @shipment.save # shorthand for courier_shipments_path(@courier) redirect_to([@courier, :shipments]) else render(:new) end end private # use a private method instead of repeating yourself def shipment_params params.require(:shipment) .permit(:tracking_number, :shipment_date) end def set_courier @courier = Courier.find(params[:courier_id]) end end
# app/views/shipments/new.html.erb <%= form_with(model: [@courier, @shipment]) do |f| %>
<%= f.label :tracking_number %> <%= f.text_field :tracking_number %><%= f.label :delivery_date %> <%= f.date_field :delivery_date %><%= f.submit %><% end %>Respondida el Dec 21, 2020 a las 08:00 - por codesculptor3f6e
Votos positivos: 0 | Votos negativos: 0 -
El error que estás experimentando ("undefined method
courier' for nil:NilClass") indica que el objeto
@shipmentes nulo y, por lo tanto, no tiene el método
courier` disponible. Esto suele ocurrir cuando el objeto no se ha inicializado correctamente o no se ha asignado a la variable antes de intentar acceder a sus atributos o métodos.En tu código, parece que estás creando un nuevo objeto
Shipment
, pero luego intentas asociar unCourier
a ese objeto sin haber asignado ningún valor a la variable@shipment
. La línea@cour_id=params[:shipment][:courier_id]
asigna el valor delcourier_id
recibido en los parámetros, lo cual es correcto, pero luego necesitas utilizar este valor para asociar elCourier
alShipment
.Te recomendaría ajustar tu código de la siguiente manera:
ruby @shipment = Shipment.new(params.require(:shipment).permit(:tracking_number, :shipment_date)) @courier = Courier.find(params[:shipment][:courier_id]) @shipment.courier = @courier if @shipment.save redirect_to shipment_path(@shipment) else render 'new' end
En este código, primero creas un nuevo objeto
Shipment
con los parámetros permitidos. Luego, encuentras el objetoCourier
correspondiente alcourier_id
recibido y lo asignas al atributocourier
del objeto@shipment
. Finalmente, guardas el objeto@shipment
y rediriges según el resultado.Asegúrate de que la asociación entre
Shipment
yCourier
esté correctamente definida en los modelos correspondientes para poder acceder a los métodos de asociación, comocourier
. Con estos ajustes, deberías poder establecer la asociación correctamente y guardar los registros de manera adecuada. ¡Espero que esto te ayude a solucionar el problema!Respondida el Dec 22, 2020 a las 08:01 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Problema con la asociación
La línea
@shipment.courier << @courier
intenta agregar un objetoCourier
a una asociaciónhas_many
, pero la asociacióncourier
en el modeloShipment
está definida comohas_one
. Para una asociaciónhas_one
, debes usar@shipment.courier = @courier
para asignar el objetoCourier
.Problema al guardar registros
Si la tabla
Shipment
no puede guardar nuevos registros, podría deberse a:Validaciones fallidas: Verifica las validaciones definidas en el modelo
Shipment
para asegurarte de que los campos obligatorios estén presentes y los valores estén dentro del rango permitido. Problemas de asociación: Asegúrate de que las asociaciones entreShipment
yCourier
estén configuradas correctamente tanto en el modeloShipment
como en el modeloCourier
. Problemas de base de datos: Verifica la configuración de tu base de datos para asegurarte de que la tablaShipment
tenga permisos de escritura y que no haya restricciones que impidan insertar datos.Solución
Para resolver estos problemas, intenta lo siguiente:
- Cambia `@shipment.courier << @courier` a `@shipment.courier = @courier` para establecer correctamente la asociación `has_one`.
- Verifica las validaciones del modelo `Shipment` y asegúrate de que se cumplan.
- Revisa las asociaciones en los modelos `Shipment` y `Courier` para asegurarte de que estén configuradas correctamente.
- Verifica la configuración de tu base de datos para asegurarte de que la tabla `Shipment` tenga permisos de escritura y que no haya restricciones que impidan insertar datos.
Código actualizado*
ruby @cour_id = params[:shipment][:courier_id] @courier = Courier.find(@cour_id) @shipment = Shipment.new(params.require(:shipment).permit(:tracking_number, :shipment_date)) @shipment.courier = @courier @shipment.save redirect_to shipment_path(@shipment) @shipment = Shipment.new(shipment_new_path) if @shipment.save redirect_to(:controller => 'shipment', :action => 'index') else render('new') end
Respondida el Dec 22, 2020 a las 08:10 - por Gemini
Votos positivos: 0 | Votos negativos: 0