How to get URL parameters from angularjs $location in Ruby on Rails? - 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?

Related

How to execute ruby function with attributes using AJAX request in Rails 6.1?

I have the following home controller:
class HomeController < ApplicationController
def index
#data = EmergencyFriend.all
#jsonData = JSON.pretty_generate(#data.as_json)
end
def about
end
def alertEmergencyContant
account_sid = "my id"
auth_token = "my token"
#client = Twilio::REST::Client.new(account_sid, auth_token)
#client.messages.create(
to: "+number 1",
from: "+number 2",
body: "hello world !"
)
end
end
Basically, in my home/index.html.erb there is only one button. When the button is pressed it shows an alert message that allows user to select an option to send an SMS to.
What I want to do is to call the alertEmergencyContant method in my home controller so that I can send the message. I also want to pass the phone_number as a parameter with that request. It has been suggested that for this I should use AJAX. I successfully installed jquery and ajax in my rails project and works as expected. What I can't understand is how to create it as a POST request.
My routes list for the home directory are :
root GET / home#index
root GET /home/about(.:format) home#about
But there is nothing on alertEmergencyContant. How to declare that in the routes and make it as a POST request? How to pass attributes from JavaScript to ruby using AJAX?
Here is my ajax request so far (This works):
$.ajax({
url: '/',
type: 'GET',
success: function(event){
alert("sending Message");
}
});
UPDATE:
def about
#thisNumber = params[:phone_number]
puts "helllloooooooooooooo " + #thisNumber
end
function ajaxRequest(){
$.ajax({
url: 'home/about/?phone_number:1244211',
type: 'GET',
success: function(event){
alert("passed");
},
failed: function(){
alert("has failed")
},
done: function(){
alert("after")
}
});
}
You need to add a route to your action
# routes.rb
post 'some_url' => 'home#alert_emergency_contact'
You can now use this in your javascript
$.ajax({
url: '/some_url', // This needs to match what you choose in routes.rb
type: 'POST',
success: function(event){
alert("sending Message");
}
});
PS: Action names are always_snake_case in Ruby, not camelCase

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

Error adding custom route to controller

I've rewritten my question to be more accurate. I have a bankaccounts controller / model.
I have the following method on my controller
def search
##ledgeritems = Ledgeritem.where("bankaccount_id = ? and transactiondate >= ? and transactiondate < ?", params[:bankaccount_id], params[:startdate], params[:enddate])
#bankaccount = Bankaccount.find(params[:bankaccount_id])
respond_to do |format|
format.js { render :partial => "bankaccount/bankledger" }
end
end
I've made two attempts to call this.
Attempt 1
Route for attempt 1
resources :bankaccounts do
post "search"
end
This shows the following route when I do a rake
bankaccount_search POST /bankaccounts/:bankaccount_id/search(.:format) bankaccounts#search
Javascript for calling attempt 1
$.ajax({
type: "POST",
url: "/bankaccounts/" + bank_account_id + "/search.js",
data: $('#edit_bankaccount_' + bank_account_id).serialize(),
success: function (result, status) {
$('#bank_ledger_div').html(result);
}
});
This calls the correct route on my controller, but the server sees it as a PUT instead of a POST and returns a 404.
Attempt 2
Route for attempt 2
resources :bankaccounts do
collection do
post "search"
end
end
This shows the following route when I do a rake
search_bankaccounts POST /bankaccounts/search(.:format) bankaccounts#search
Javascript for calling attempt 2
$.ajax({
type: "POST",
url: "/bankaccounts/search.js",
data: $('#edit_bankaccount_' + bank_account_id).serialize(),
success: function (result, status) {
$('#bank_ledger_div').html(result);
}
});
This calls the update route but still showing as a PUT command. In Firebug I see a 500 error with the following result
Couldn't find Bankaccount with id=search
Usually this error means you're making a GET request instead of a POST request.
For example:
GET /bankaccounts/search is assumed to be requesting the SHOW page for a bankaccount with ID = search
While
POST /bankaccounts/search would correctly hit your action.
Edit:
resources :bankaccounts do
collection do
post "search"
end
end
Is correct as well. Now I'm noticing that you are doing this to get your data:
data: $('#edit_bankaccount_' + bank_account_id).serialize()
that form likely has a hidden field in it, put there by rails, with name='_method' and value='PUT'. That is what is convincing rails that your POST is really a PUT. You'll need to remove that from the serialized data in order to correctly post the form.
If you want the /search url to be used without specifying an id, you should declare it as a collection action :
resources :bankaccounts do
collection do
post "search"
end
end
You can check the routes defined in your app with the rake routes command, to ensure that you defined what you meant.
The URL is expecting the format
/bankaccounts/:bankaccount_id/search
Is the error coming from this method? Could /bankaccounts/search be matching another route?

How to insert into table using link tag

I have ArtistProduct model. User enters the product details, user can view the entered details in modal window by clicking the preview link before saving the details.
I'm trying to save the data using AJAX by passing all the details like params when it is validated, but it not saving the database.
In view I'm calling AJAX:
var theVal=id+'/'+artist_id+'/'+name+'/'+desc+'/'+price+'/'+story+'/'+artist_name+'/'+dimension+'/'+material+'/'+contact
var theURL = '/add_temp/' + theVal;
$.ajax({
url: theURL
});
In controller I'm handling it like so:
def add_temp
#pro_id=ArtistProduct.where("id=?",params[:id])
if #pro_id.nil?
#artistprod = ArtistProduct.new(:artist_id=>58, :product_name=>params[:name], :description=>params[:desc], :product_price=>params[:price], :product_story=>params[:story],:artist_name=>params[:artist_name], :dimensions=>params[:dimension],:material=>params[:material],:contact_number=>params[:contact])
#artistprod.save
end
end
UPDATE
Thanks for your reply.
Now am getting Routing error.
In my Router I have like:
match 'add_temp/:id/:artist_id/:name/:desc/:price/:story/:artist_name/:dimension/:material/:contact'=> 'artist_products#add_temp'
UPDATE
Routing Error404 Not Found
No route matches [POST] "/add_temp/P58018/58/Prod/swsx/50/sfdf/null/null/0"
UPDATE
Ya i identified it and corrected it but still also values are not saving into the database. Please help me
In Controller i am doing like so:
def add_temp
if !(ArtistProduct.where("id=?",params[:id]).exists?)
#artistprod=ArtistProduct.new(:id=>params[:id],:artist_id=>58, :product_name=>params[:name], :description=>params[:desc], :product_price=>params[:price], :product_story=>params[:story],:artist_name=>params[:artist_name], :dimensions=>params[:dimension],:material=>params[:material],:contact_number=>params[:contact])
#artistprod.save
respond_to do |format|
format.html { redirect_to #artistprod.addproduct }
format.js
end
end
end
Hi dbkooper, Thanks for your answer. I tried answer given by u but am getting Routing error
In view am calling like:
var theURL = '/artist_products/'+id+'/add_temp?artist_id='+artist_id+'product_name='+name+'description='+desc+'product_price='+price+'product_story='+story+'artist_name='+artist_name+'dimensions='+dimension+'material='+material+'contact_number='+contact;
The big problem I see is that your $.ajax call is missing some options. By default, $.ajax defaults to a GET request if no type is specified.
You should change it to:
$.ajax({
type: 'POST',
url: theURL,
success: function (json) {
// handle your success here
},
error: function (response) {
// handle your errors here
}
});
This way, you specify that it will be a POST request and you also have callback methods for handling success and error
I think your routes should be
resources artist_products do
member do
post 'add_temp'
end
end
use rake :routes to get the correct routes
most probab it will be "artist_products/:id/add_temp"
For ajax request it will be you can send the val param's using ? to the url
like
var theURL = '/artist_products/'+id+'/add_temp?artist_id='+artist_id+'so on..';
$.ajax({ url: theURL });
Inside your controller
you can access params as usual

How to access Jquery's Ajax call in RoR?

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'
}
});

Resources