Hello, I want to validate that it is not empty, that I have to choose one of the options. Thank you.
view
<% if @reunion.errors %>
<div class="error">
<p>Se han encontrado los siguiente errores:</p>
<ul>
<% @reunion.errors.full_messages.each do |error| %>
<li><%= error %></li>
<% end %>
</ul>
</div>
<div class = "row">
<div class = "col-md-2"></div>
<div class ="col-xs-12 col-sm-4 col-md-3">
<label>Negocio</label>
<%= select_tag "negocio", options_from_collection_for_select(@negocios, "id", "nombre"),
class: "form-control", :include_blank => "Seleccione Pais" %>
</div>
<div class ="col-xs-12 col-sm-4 col-md-3">
<label>region</label>
<%= select_tag "region", "<option value="">Seleccione region</option>".html_safe,
class: "form-control" %>
</div>
<div class ="col-xs-12 col-sm-4 col-md-2">
<label>ciudad</label>
<%= select_tag "ciudad", "<option value="">Seleccione una ciudad</option>".html_safe, class: "form-control" %>
</div>
<div class = "col-md-2"></div>
</div>
<div class = "row">
<div class = "col-md-2"></div>
<div class ="col-xs-12 col-sm-4 col-md-2">
<label>Planta</label>
<%= select_tag "reunion[planta_id]","<option value="">Seleccione una planta</option>".html_safe, class: "form-control" %>
</div>
</div>
controller
class ReunionesController < ApplicationController
before_action :set_reunion, only: [:show, :edit, :update, :destroy]
autocomplete :centro_costo, :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
# GET /reuniones/1
# GET /reuniones/1.json
def show
end
# GET /reuniones/new
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
@negocios = Negocio.all
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: 'La reunión se creó correctamente.' }
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
# PATCH/PUT /reuniones/1
# PATCH/PUT /reuniones/1.json
def update
respond_to do |format|
if @reunion.update(reunion_params)
format.html { redirect_to @reunion, notice: 'La reunión se actualizó correctamente.' }
format.json { render :show, status: :ok, location: @reunion }
else
@negocios = Negocio.all
format.html { render :edit }
format.json { render json: @reunion.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reuniones/1
# DELETE /reuniones/1.json
def destroy
@reunion.destroy
respond_to do |format|
format.html { redirect_to reuniones_url, notice: 'Reunión fue destruida con éxito.' }
format.json { head :no_content }
end
end
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,:_destroy])
end
end
javascript
$(document).on('turbolinks:load', function(){
// Empieza codigo para select anidados
$("#negocio").change(function(event, data) {
var id_negocio = $('select#negocio :selected').val();
$.ajax({
url: '/reuniones/select_region',
dataType: "JSON",
type: 'GET',
data: { idnegocio: id_negocio },
success: function(data) {
var $select = $('#region');
$select.empty().append('<option value="">Seleccione Region</option>');
$(data).each(function (index, o) {
var $option = $("<option/>").attr("value", o.id).text(o.nombre);
$select.append($option);
});
}
});
// inicializar los selects
var $select = $('#reunion_planta_id');
$select.empty().append('<option value="">Seleccione ciudad</option>');
});
$("#region").change(function(event, data) {
var id_region = $('select#region :selected').val();
$.ajax({
url: '/reuniones/select_ciudad',
dataType: "JSON",
type: 'GET',
data: { idregion: id_region },
success: function(data) {
var $select = $('#ciudad');
$select.empty().append('<option value="">Seleccione una ciudad</option>');
$(data).each(function (index, o) {
var $option = $("<option/>").attr("value", o.id).text(o.nombre);
$select.append($option);
});
}
});
});
$("#ciudad").change(function(event, data) {
var id_ciudad = $('select#ciudad :selected').val();
$.ajax({
url: '/reuniones/select_planta',
dataType: "JSON",
type: 'GET',
data: { idciudad: id_ciudad },
success: function(data) {
var $select = $('#reunion_planta_id');
$select.empty().append('<option value="">Seleccione la planta</option>');
$(data).each(function (index, o) {
var $option = $("<option/>").attr("value", o.id).text(o.nombre);
$select.append($option);
});
}
});
}); // Termina codigo para select anidado
}); //select reuniones fin de select
Reunion.rb
class Reunion < ApplicationRecord
belongs_to :planta
end
Use validation
presence
to validate that an attribute contains data (ie it is not blank), for example:This will cause an error to be generated in said object when saving a type
Reunion
object and, therefore, the record will not be saved. You can get that error by callingerrors
on the object.For example, in your case, I wouldn't change anything in your controller, your action
create
would look the same, but running this line:If any of the attributes that have validation
presence: true
are blank (ie the user did not specify them), for examplehora_pedido
, an error with text similar to"Hora Pedido can't be blank"
1 will be added to@reunion.errors
.So, all you have to do is include a section in your view where this error is displayed (if it exists), for example, you could add this code to the top of your view 2 :
That code will show the errors that are found, if there are no errors, nothing will be shown.
The only thing you have to do is add as many validations as you need in your model, the code to display the errors does not change anymore.
To know the available validations I recommend you consult the Rails guides (content in English).
1 Messages can be translated into
config/locales/
.2 Put the code and style it appropriately according to the design of your application.
This error is thrown because the parameter
centro_costo_fullname
is empty (ie no value was provided in the form), which causes the value ofcentro_costo
increate
your controller action to benil
:Therefore, trying to assign the value
centro_costo.id
to@reunion.centro_costo_id
generates the errorNoMethodError
(centro_costo
beingnil
cannot respond toid
).To correct it, we simply have to check if it
centro_costo
can respond to the methodid
before making the corresponding assignment, an action that we can achieve withtry()
.Update the
create
controller action so that the line where the assignment is made is:So, if it's a valid
centro_costo
object , it will be able to respond to and thus allocate the corresponding one; but if it is not, then it will assign .CentroCosto
id
id
nil
I recommend that you also consider adding a validation layer with javascript / jQuery to offer a better user experience (as well as avoid sending data to the server with each user error).