I am trying to hit the database at the exit of a field without reloading the form using Ajax. The controller must do some process on the data obtained from the database and respond to the view. The user will then continue with the input.
I am missing something and just can't see what is wrong. I have the same piece of code working in a Rails 3.2 application without a problem. In Rails 3.2 the request goes to the check_matricula
method, but in Rails 4, it goes to the show
action.
The following code is not working in my Rails 4 app:
Gemfile
gem 'responders', '~> 2.0'
View
<div class="field">
<%= f.text_field :matricula, { "data-remote" => true, "data-url" => "/liquidaciones_de_viajes/check_matricula", "data-type" => :json, :size => 10 } %>
<span id="check_matricula"> </span>
</div>
Controller
class LiquidacionesDeViajesController < ApplicationController
respond_to :html, :json
def check_matricula
@matricula = Matricula.find_by_codigo(params[:liquidacion_de_viajes][:matricula])
# ... some process that result in matricula_ok true or false ...
if matricula_ok
respond_with(@matricula.empresa.razon_social)
else
respond_with(nil)
end
end
end
assets/javascripts/check_matricula.js
$(document).ready(function() {
$("#liquidacion_de_viajes_matricula").bind('ajax:success', function(evt, data, status, xhr) {
if (data !== null) {
$('#razon_social').html(data.razon_social);
$('#check_matricula').html('');
} else {
$('#check_matricula').html('Error de matricula');
$('#razon_social').empty();
}
});
$("#liquidacion_de_viajes_matricula").live('ajax:before', function() {
if ($(this).val() == '') {
return false;
}
});
$("#liquidacion_de_viajes_matricula").focus(function() {
$('#check_matricula').empty();
$('#razon_social').empty();
});
});
I see in console a GET is there but I did a POST in the route:
Started GET "/liquidaciones_de_viajes/check_matricula?liquidacion_de_viajes%5Bmatricula%5D=5555" for 127.0.0.1 at 2016-05-30 15:00:50 -0300
Processing by LiquidacionesDeViajesController#show as JSON
Parameters: {"liquidacion_de_viajes"=>{"matricula"=>"5555"}, "id"=>"check_matricula"}
Please change your response in Json
def check_matricula
@matricula = Matricula.find_by_codigo(params[:liquidacion_de_viajes][:matricula])
... some process that result in matricula_ok true or false ...
if matricula_ok
respond_to do |format|
format.html
format.json{
render :json => @matricula.empresa.razon_social.to_json
}
end
else
respond_with(nil)
end
end
You simply need to specify the check_matricula
route for your contoller:
resources : liquidaciones_de_viajes do
collection do
post `check_matricula`
end
end
Without this route, Rails assumes that check_matricula
is the :id
portion of the show
route.
To send the requests to the URL via POST
, add the data-method: :post
option to your text_field
, like so:
<%= f.text_field :matricula, { data-remote: true, data-url: "/liquidaciones_de_viajes/check_matricula", data-type: :json, data-method: :post, size: 10 } %>