Hello, I am making a form and it requires an autocomplete and selects but in the routes; when i go to save i get an error.
the screen throws an error stays in validation. I place the log
My code:
Model
reunion.rb
class Reunion < ApplicationRecord
belongs_to :centro_costo
def centro_costo_fullname
centro_costo.fullname if centro_costo
end
def centro_costo_fullname=(fullname)
self.centro_costo = CentroCosto.find_by_fullname(fullname) unless fullname.blank?
end
end
routes
resources :reuniones do
collection do
get :autocomplete_centro_costo_fullname
get :select_region
get :select_ciudad
get :select_planta
end
end
controller
class ReunionesController < ApplicationController
before_action :set_reunion, only: [:show, :edit, :update, :destroy]
autocomplete :cost_center, :fullname, :full => true, :column_name => 'fullname'
# GET /reuniones
# GET /reuniones.json
def index
@reuniones = Reunion.all
@negocios = Negocio.all
end
def select_region
rs = Region.where(:negocio_id => params[:idnegocio]).order('nombre').all
respond_to do |format|
format.json {render json: rs }
format.html
end
end
def select_ciudad
rs = Ciudad.where(:region_id => params[:idregion]).order('nombre').all
respond_to do |format|
format.json {render json: rs }
format.html
end
end
def select_planta
rs = Planta.where(:ciudad_id => params[:idciudad]).order('nombre').all
respond_to do |format|
format.json {render json: rs }
format.html
end
end
def new
Time.zone = 'America/Bogota'
@reunion = Reunion.new(fecha_entrega: Time.zone.now.strftime("%d/%m/%Y"))
@reunion.detalles_reuniones.build
@negocios = Negocio.all #para javascript
end
# GET /reuniones/1/edit
def edit
end
# POST /reuniones
# POST /reuniones.json
def create
centro_costo = CentroCosto.find_by(fullname:reunion_params[:centro_costo_fullname])
@reunion = Reunion.new(reunion_params)
@reunion.centro_costo_id = centro_costo.id
respond_to do |format|
if @reunion.save!
format.html { redirect_to @reunion, notice: 'Reunion was successfully created.' }
format.json { render :show, status: :created, location: @reunion }
else
@negocios = Negocio.all
format.html { render :new }
format.json { render json: @reunion.errors, status: :unprocessable_entity }
end
end
end
end cost_center is an association.
private
# Use callbacks to share common setup or constraints between actions.
def set_reunion
@reunion = Reunion.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def reunion_params
params.require(:reunion).permit(:hora_pedido, :fecha_pedido,
:hora_inicio, :hora_final, :fecha_entrega, :observacion, :subtotal,
:planta_id, :ubicacion,:centro_costo_fullname,:hora_entre,:nombre,
#Aca esta el maestro de detalle.
detalles_reuniones_attributes: [:id,:reunion_id, :cantidad, :valor, :producto_id, :hora_entrega,:_destroy])
end
The error is because your form is only sending the attribute
centro_costo_fullname
and your objectReunion
needs the attributecentro_costo_id
(this is because of the associationbelongs_to :centro_costo
).So when trying to save the record to your controller (ie
@reunion.save
), validation fails since you're not giving that attribute (in rails 5 relationsbelongs_to
require that theid
related is always present unless otherwise stated).To solve it you have two options.
centro_costo_id
.id
usingcentro_costo_fullname
and assign it manually.I recommend the second option because I consider it to be simpler. To do this you need to get the cost center from your model and assign its
id
to@reunion
.For example, you could get cost center 1 like this :
And then you assign the
id
to@reunion
:So, this is what
create
the controller action would look like:1 I assume that your method
reunion_params
allows the attributecentro_costo_fullname
.In case the validation still fails, you can modify your code so that it shows an error instead of returning an
false
(which in your log is identified only by therollback
).To do so, in the
create
controller action, change this line:For this other:
And note the error that will be displayed in the console when you try to create a
Reunion
.Once you identify the error you should return your action code
create
to@reunion.save
, otherwise users will get error screens when they enter wrong data (instead of more friendly messages).