How to access Jquery's Ajax call in RoR? - ruby-on-rails

Guys I'm really novice to this RoR, and at this moment i reached to complex situation that "how to use Jquery's ajax() call in RoR?"
I've a controller called Projects like this
class ProjectsController < ApplicationController
def stagemilestone
#milestones=Milestone.find_by_sql("SELECT name, created_at FROM milestones WHERE stage=1")
end
end
and i want to call this action from jquery's ajax call and return the data, for this I'm using like this
$.ajax({
url: "/projects/stagemilestone",
success: function(){
//here i need the returned data from controller
// means output of #milestones
}
});
So please help me, how to do this?

Guys finally i found Solution as Follows and working Great!!
Controller
def stagemilestone
#milestones=Milestone.find(:all, :conditions => ["status_id=? and project_id=?",params[:stageid], params[:id]])
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #milestones}
end
end
and My char.js looks like this
$.ajax({
type : 'get',
url : "/projects/stagemilestone",
data : "stageid=" + $(this).attr('name') + "&id=" + $.cookie('projectid'),
dataType : 'json',
async : false,
context : document.body,
success : function(response) {
}
});

I think what you want is to use "respond_to"
like this
class ProjectsController < ApplicationController
def stagemilestone
#milestones=Milestone.find_by_sql("SELECT name, created_at FROM milestones WHERE stage=1")
respond_to do |format|
format.js {render :json => #milestones}
end
end
end
Here's more info on respond_to, http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to
UPDATE: you may want to double check the accept's header of your ajax request (you can look at the request in firebug), you may need to use format.json. Refer here for the full list of MIME types and just make sure they match up:
http://apidock.com/rails/Mime

Add a parameter to your success callback; that will contain the response value.
success: function(response)
{
// response will be the HTTP / JSON / text returned from your controller
}

Just add a parameter to the callback function, like:
$.ajax({
url: "/projects/stagemilestone",
success: function(output){
//Do something with 'output'
}
});

Related

How to get URL parameters from angularjs $location in Ruby on Rails?

I'm showing a database table using ruby on rails, and I'd like to sort the columns whenever I click on the column title.
My idea was to call an angularjs function that adds a parameter like ?sort_by=id to the url and get it back in my ruby controller to do the ordered request, but it seems like it's not working.
Here is the part of my users.html.haml file which calls the function :
%th
%button{'ng-click': 'sort_by("product")'}
My angularjs function (users.controller.js) :
$scope.sort_by = function(str){
$location.search({sort_by: 'product'});
$window.location.reload();
}
And index function in users_controller.rb
def index
#users = User.all
max_per_page = 50
puts params
paginate #users.size, max_per_page do |limit, offset|
render json: #users.limit(limit).offset(offset)
end
end
When I click on the button, it reloads the page with ?sort_by=product in the url and calls the index function, but puts params still returns {"subdomain"=>"admin", "controller"=>"admin/users", "action"=>"index"}
How can I make this work ?
Thanks in advance.
I used an $http get request with params and it finally worked, in case it helps someone :
$http({
method: 'GET',
url: 'users',
dataType: 'json',
params: {
'sort_by': 'products.name',
},
headers: {
"Content-Type": "application/json"
}
}).success(function(response){
console.log('succes');
}).error(function(error){
console.log('err');
});
and then in index method in users_controller.rb :
puts request.params['sort_by'] if !request.params['sort_by'].nil?

Rails - AJAX window.location redirect not working

In my Rails app, stringified JSON form input is passed to a controller via AJAX - on success, the user is to be redirected to a summary page, but the AJAX redirect doesn't seem to be working...
$.ajax({
url: "report/submission",
type: "POST",
beforeSend: function(xhr) {xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"))},
data: {"report" : reportParameter},
success: function(response) {
window.location.href = "/report/summary";
}
});
and the associated controller
def submission
#incomingReport = ActiveSupport::JSON.decode(params[:report])
#newReportIDArray = Array.new
#incomingReport.each do |x|
hash = ActionController::Parameters.new(x)
#new_report = Report.new(report_params(hash))
#new_report.save
end
end
Everything else seems to work just fine - the data is entered, but the redirect does not trigger. I've searched all around and it looks like this is the syntax that everyone says to use, but it doesn't seem to work for me. I'm sure that I am doing something wrong, but I'm not sure what.
Editing to clarify problem/solution
During a chat with #Jonathan and #Kumar, I noted that window.open("/report/summary") did work correctly - #Jonathan suggested that I just try console.log(window.location) before the ajax call, and to my surprise, the script from a function from elsewhere in my app was logged. Big shocker now - THE FUNCTION WAS CALLED location()!!! Renaming the function and then restarting the app in a new window solved the problem. Learn from my mistake, kids - don't name a function location().
Ruby isn't my first language but it doesn't look like you're sending a response back. Try returning something or putsing. Look up how to do that with rails, a proper response. Maybe render json: [success: 200] or something like that. Maybe it's irrelevant. In any case, if it's not working try changing success for complete and log out the response to debug. The complete will always fire, but success won't always.
Try this:
respond_to do |format|
format.json do
render json: {
success: 200
}.to_json
end
end
In your AJAX setup, add "datatype": "json".
You could improve the response to conditionally send a failure like success: 500 if something went wrong.
You don't really need respond_to block here because you're always expecting JSON, but that's the kind of format that's often used in Rails if not mistaken.
If that doesn't work just use the render json: part as that is definitely a return.
Update
Further from our discussion it turns out that after making a robust Ajax call and tweaking the action, the final hurdle was a window.location that was not working. The cause of the problem was that location had been rebound to another function. All that needed to be done in the end is to rename that custom function and Bob's your uncle.
Add a datatype
$.ajax({
url: "report/submission",
type: "POST",
dataType: 'json', #Add json data type, as we'll render json from controller
beforeSend: function(xhr) {xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"))},
data: {"report" : reportParameter},
success: function(response) {
console.log("Response is ", response);
//When we get 200, this function should execute
window.location.href = "/report/summary";
},
error: function(error){
console.log("Error is ", error);
}
});
And in the controller
def submission
#incomingReport = ActiveSupport::JSON.decode(params[:report])
#newReportIDArray = Array.new
#incomingReport.each do |x|
hash = ActionController::Parameters.new(x)
#new_report = Report.new(report_params(hash))
#new_report.save
end
respond_to do |format|
format.json { head :ok } #This will return 200 status back to ajax call
end
end

Rails4: Passing non-forum data from front end to the back end, and processing it

Ok. So I have a small XHR request where json is returned. On success the json is passed like this.
var myArr = JSON.parse(xmlhttp.responseText);
myMainFunction(myArr);
function myMainFunction(arr) {
var vShipTypeID = arr[0].victim.shipTypeID;
}
I need to send vShipTypeID to rails. My goal is to be sending this value back to activerecord and the information returned will go within a js, or json file to the respond_to statement in the controller.
#shipName = InvType.find(vShipTypeID).name
Here's the main idea. The client sends out the ID of the ship to rails, and rails returns the ship's name.
I know how to make the Ajax request.
I don't know how to process the request on the server end. Meaning after rails receives the data, where do I find it, and how to I convert it to be usable so that I can make an activerecord statement out of the value I received from the client?
Anyone?
A simple solution could be defining an action on your ship controller and define a route to it for example define a route in your routes.rb
get "/ship/:id/getname" => "ship#getname"
in your js file
$.get( "/ship/"+vShipID+"/getname")
.done(function(data) {
alert( "Ship name: " + data.name );
})
.fail(function() {
alert( "error" );
});
in you ship_controller.rb
class ship_controller <ApplicationController
....... #other methods
def getname
#shipname = Ship.find(params[:id]).name
if request.xhr
render :json => {name: #shipname} and return
else
redirect_to ship_path(params[:id])
end
end
........ #some other methods
end
You need to handle json requests in your controller check this question for details
for a quick example in your controller create a new action getnamefromid and call that controller from your client.
respond_to do |format|
format.json { render :json => #shipName }
end

How does my ajax call know where my json is in rails

I have a javascript file with some ajax in it as follows.
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: 'data',
dataType: 'json',
success: function (data) {
draw(data);
},
error: function (result) {
error();
}
});
I also have created a method in a controller which renders json.
class GraphController < ApplicationController
def index
end
def data
render :json => User.select('value').map(&:value)
end
end
So my question is, how does rails know where the json is coming from especially as I'm not returning a physical file from my controller. What happens if I also have a physical .json file in my folder structure? Is there a heirarchy of how a view will look for a json file (eg physical file>jbuilder file>controller action)?
Every Action must render something.
Either you render something explicitly or rails will look for a page with name similar to the action in inside respective controller's folder in views.
You may render an html.erb, .json, .haml etc from views( provided you specify respond to format)
If you are rendering someting explicitly (which is true in your case, as json) Rails wont bother to look into views folder.
Or otherwise you may just skip render :json statement and specify that object in .json file, with respond to :json.
Here in your scenario, you are rendering a json object, which will be accepted in the success: section of the AJAX function's data arguement.
in ajax call.. contentType: "application/json; charset=utf-8", defines what is the type of request you are querying with rails.What that says is, "if the client wants HTML in response to this action, just respond as we would have before, but if the client wants XML, return them the list of people in XML format." (Rails determines the desired response format from the HTTP Accept header submitted by the client.).
Take a look respond_to api how rails responds to different types of request -js/xml/html/json
so you can try this in your controller as well..edit the data action like this and try..any call to data such as js/html/xml/json will work and rails will understand what type of response it needs to send.
def data
format.html { redirect_to(user_list_url) }
format.js
format.xml { render :xml => #users.to_xml(:include => #accounts) }
format.json {render :json => User.select('value').map(&:value) }
end
to render any error from controller to view..can be done like this:-
if #user.present?
format.json {render :json => User.select('value').map(&:value) }
else
format.js { render :json => #user.errors.full_messages.join(' '),
:status => 400 }
end
use this in view in ajax.error function like this
.error(function(data) {
$("#show_error").html("An Error Occurred,Please try again.");
});
HOPE THIS HELPS

Rails + ajaxForm: Use the 'error' callback when error uploading file

Background
I first wanted to upload a file via json and get a response in that way as well.
I'm using:
Rails 3
ajaxForm
I soon found out that you can't get a reponse in json. So, I follow that advice and returned as text.
I'm able to get things working after removing the pre tags. Ugly solution, but it's an ugly problem.
Problem
Now, my problem is handling errors.
Here's the JS:
$('form#new_image').submit(function() {
$(this).ajaxSubmit({
dataType: 'text',
beforeSubmit: showLoading,
success: imageUploadSuccess,
error: imageUploadError
});
return false;
});
function imageUploadSuccess(data) {
var jsonObject = $.parseJSON((/<pre>(.+)<\/pre>/.exec(data))[1]);
//Do something
}
function imageUploadError(data) {
alert("FAIL!");
}
Even if I respond with an error, the success callback (imageUploadSuccess) is always executed.
Here's my controller:
def create
#image = Image.new params[:file]
#image.imageable_type = params[:imageable_type]
#image.imageable_id = params[:imageable_id]
respond_to do |f|
if #image.save
logger.debug "PASSED"
f.text {render :text => #image.to_json}
else
logger.debug "FAIL"
f.text { render :text => "Fail!", :status => 500 }
end
end
end
Now, while I could return a json object with success: false in it when it fails, it just feels dirty that the success callback is always executed.
How do I make use of the error callback?
Here is some generic jQuery code to make your ajax submission:
$('#btn-submit').click(function(event){
event.preventDefault();
$.ajax({
type: "POST",
url: $('form').attr('action'),
data: $('form').serialize(),
success: function(data) {},
error: function(data) {}
});
});
EDIT:
I just saw you're willing to upload file with ajax. Ajax doesn't allow this kind of processing, but there are great alternatives.
I give two examples here (two branches): https://github.com/apneadiving/Pic-upload---Crop-in-Ajax
with uploadify using flash
with jQuery Uploader, 100% js (using frames)
It seems that whether you use .ajax or .ajaxForm to submit it, as long as the server responds, the success callback will be executed.
So, I have to reply with specially structured json that has a success: true/false depending on the situation. It's best illustrated with the controller action (I'm using inherited_resources here, but you get the idea):
def create
create! do |success, failure|
success.html {redirect_to to}
success.text do
image = {
:id => #image.id,
:file_name => #image.file_name,
:success => true
}
render :text => image.to_json
end
failure.text do
image = {
:success => false,
:errors => #image.errors
}
render :text => image.to_json
end
success.js
end
end

Resources