I'm unable to pass a variable to my controller using the data parameter of an AJAX call. What am I doing wrong?
show.html.erb
var parentStepID = 20;
$.ajax({
url: "/steps/create_branch",
type: 'GET',
data: {parent: parentStepID}
});
controller
def create_branch
parentStepID = params[:parent]
logger.debug("parentStepID: #{parentStepID}")
respond_to do |format|
format.js
end
end
The logger does not seem to get the parentStepID:
Started GET "/projects/20/steps/create_branch" for 127.0.0.1 at 2013-03-06 11:56:44 -0500
Processing by StepsController#create_branch as HTML
Parameters: {"project_id"=>"20"}
Project Load (0.1ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1 [["id", "20"]]
####################################################################
parentStepID:
Rendered steps/create_branch.js.erb (0.1ms)
Completed 200 OK in 16ms (Views: 10.6ms | ActiveRecord: 0.1ms)
Browser console:
20 0:412
/projects/20/steps/create_branch 0:413
Also, I believe the AJAX request is working properly; I created a file called "create_branch.js.erb"' in my steps views folder and put in an alert that is successfully called.
Related
Only on Rails 6 when:
I receives a json response on pages with url like:
www.site.com/foo
and not when url is like:
www.site.com/foo?q=x
to reproduce:
rails new todo
rails scaffold Todo task:string
rails db:migrate
rails server
Create a task
In file show.json.jbuilder you'll see:
json.partial! "todos/todo", todo: #todo
Go to show page (todo/1)
Type on browser's console to se json response:
$.ajax({
url: window.location.href + ".json",
dataType: 'json',
async: false
});
When your url is "todo/1" jbuilder loads ok:
Started GET "/todos/1.json" for ::1 at 2019-10-28 13:55:54 -0300
Processing by TodosController#show as JSON
Parameters: {"id"=>"1"}
Todo Load (0.3ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/todos_controller.rb:67:in `set_todo'
Rendering todos/show.json.jbuilder
Rendered todos/_todo.json.jbuilder (Duration: 1.0ms | Allocations: 125)
Rendered todos/show.json.jbuilder (Duration: 2.2ms | Allocations: 306)
Completed 200 OK in 10ms (Views: 3.9ms | ActiveRecord: 0.3ms | Allocations: 1565)
But if your url is "todo/1?q=foo" you have no data:
Started GET "/todos/1?q=foo.json" for ::1 at 2019-10-28 13:55:44 -0300
Processing by TodosController#show as JSON
Parameters: {"q"=>"foo.json", "id"=>"1"}
Todo Load (0.2ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/todos_controller.rb:67:in `set_todo'
Rendering todos/show.html.erb within layouts/application
Rendered todos/show.html.erb within layouts/application (Duration: 0.7ms | Allocations: 89)
Completed 200 OK in 25ms (Views: 21.3ms | ActiveRecord: 0.2ms | Allocations: 6547)
Obs: I opened this rails github issue
In order to work in rails 6.0.0 we need to explicitly tell to use json format when the url has queries:
todos_controller.rb
change from:
def show
end
to:
def show
respond_to do |format|
format.html
format.json
end
end
This is because the request must be in the following form:
www.site.com/foo.json?q=x
If you want to pass parameters to the request, you can use the data parameter of ajax.
For instance:
$.ajax({
url: "/todos",
type: "GET",
data: {
id: 1,
q: "x"
},
success: function (response) {
console.log(response.data)
}
})
If I have a url like localhost:3000?id=2 what do I need to change to get my AJAX call to use the param?
page_controller.rb
class PageController < ApplicationController
def index
#pId = params[:id]
#p = Plant.where(id: #pId)
respond_to do |format|
format.json { render json: #p.to_json }
format.html
end
end
end
page.coffee
$ ->
$.ajax
dataType: 'json'
url: 'index.json'
success: (data) ->
alert "Data #{JSON.parse(data)} ---"
development.log for one page load
Processing by PageController#index as HTML
Parameters: {"id"=>"2"}
Rendering page/index.html.erb within layouts/application
[1m[36mPlant Load (1.0ms)[0m [1m[34mSELECT "plants".* FROM "plants" WHERE "plants"."id" = $1[0m [["id", 2]]
Rendered page/index.html.erb within layouts/application (3.0ms)
Completed 200 OK in 80ms (Views: 69.5ms | ActiveRecord: 1.0ms)
Started GET "/index.json" for ::1 at 2017-01-26 08:07:18 -0800
Processing by PageController#index as JSON
[1m[36mPlant Load (1.0ms)[0m [1m[34mSELECT "plants".* FROM "plants" WHERE "plants"."id" IS NULL[0m
Completed 200 OK in 5ms (Views: 0.1ms | ActiveRecord: 1.0ms)
This is just a very basic example taken from a much more complicated piece of code. Everything in my original code works except for when I'm trying to access to param.
update 1
routes.rb
Rails.application.routes.draw do
get 'index' => 'page#index'
root "page#index"
end
Your URI for the Ajax request doesn't include the parameter. You're making a call to index.json and not index.json?id=1
I have an HTML table that displays order items. On each table row I have a "Need By Date" field that is standalone(not in a form) input field. Whenever a user changes the date, I post this date to the server to save it against the order.
I am noticing that when I use OrderItem.update or OrderItem.update_attributes from the rails console it works, but when it is triggered from a field change event Rails does not trigger an update to the table.
#JavaScript
$(".order-item.datepicker").change ->
needby_date = $(this).val()
order_item_url = $(this).data("order-item-url")
$.ajax
type: "POST"
url: order_item_url
data:
needby_date: needby_date
My controller -
def update_needby_date
#order_item = OrderItem.find(params[:order_item_id])
#order_item.update_attribute(update_needby_date_params)
respond_to do |format|
format.js { render :nothing => true }
end
end
private
def update_needby_date_params
params.permit(:order_item_id, :needby_date)
end
As you can see in the log file, the update is not being triggered -
Started POST "/order_items/1/update_needby_date" for 127.0.0.1 at 2014-07-08 10:55:10 -0400
Processing by OrderItemsController#update_needby_date as */*
Parameters: {"needby_date"=>"07/23/2014", "order_item_id"=>"1"}
OrderItem Load (0.4ms) SELECT "order_items".* FROM "order_items" WHERE "order_items"."id" = ? LIMIT 1 [["id", "1"]]
(0.4ms) begin transaction
(0.2ms) commit transaction
Rendered text template (0.1ms)
Completed 200 OK in 16ms (Views: 3.3ms | ActiveRecord: 1.0ms)
I have some javascript that displays some data from my database on my webpage. I also have a button that when the user clicks it some logic occurs in the controllers and then I want to have the data displayed changed. However, at the momment when they click the button nothing happens (page is not reloaded). Could you guys help me set that up? Here is what I have so far:
controller:
class QtlsController < ApplicationController
require 'json'
require 'uri'
$rollback = nil
def index
logger.debug "\nrollback is: #{$rollback}\n"
render "index"
end
def rollback
$rollback = params[:version].gsub(/"/,'')
redirect_to :action => :index
end
end
view:
<%- if $rollback.nil? %>
generates one type of table
<%- else %>
generates another type of table
<%- end %>
...some other logic and buttons etc...
jQuery(function() {
jQuery( "#rollback").button();
jQuery( "#rollback").click(function() {
var version = getSelectedText('version_selector');
jQuery.ajax({
type: "POST",
headers: {
'X-Transaction': 'POST Example',
'X-CSRF-Token': jQuery('meta[name="csrftoken"]').attr('content')
},
url: "/qtls/rollback",
data: {version: JSON.stringify(version) },
dataType: 'json',
sucess: function() { alert("Success! Rollbacked"); }
});
});
Here is what is in log files when I go to the page and when I click the rollback button:
Started GET "/qtls" for 10.64.229.59 at Tue Jul 17 16:48:52 -0500 2012
Processing by QtlsController#index as HTML
rollback is:
ROLLBACK IS NIL!!!
Qtl Load (2.0ms) SELECT `qtls`.* FROM `qtls`
Rendered qtls/index.html.erb within layouts/application (404.8ms)
Rendered shared/_user_nav.html.erb (1.3ms)
Rendered shared/_nav.html.erb (1.3ms)
Rendered shared/_footer.html.erb (0.6ms)
Completed 200 OK in 544ms (Views: 540.9ms | ActiveRecord: 2.0ms)
Started POST "/qtls/rollback" for 10.64.229.59 at Tue Jul 17 16:48:57 -0500 2012
Processing by QtlsController#rollback as JSON
Parameters: {"version"=>"\"test1\""}
Redirected to http://10.10.136.244:4000/qtls
Completed 302 Found in 3ms (ActiveRecord: 0.0ms)
Started GET "/qtls" for 10.64.229.59 at Tue Jul 17 16:48:58 -0500 2012
Processing by QtlsController#index as JSON
rollback is: test1
Rendered qtls/index.html.erb within layouts/application (37.7ms)
Rendered shared/_user_nav.html.erb (3.3ms)
Rendered shared/_nav.html.erb (4.3ms)
Rendered shared/_footer.html.erb (2.0ms)
Completed 200 OK in 99ms (Views: 97.4ms | ActiveRecord: 0.0ms)
it's a reaaaaaally bad style to use global variables like $rollback!
if you want to store user-data use your session-object.
use the jquery-rails gem to integrate with jQuery in your views and then use the :remote => :true in your form, so that rails can handle the form-submission.
I've tried looking at other answers for this but I can't seem to figure out why my redirect isn't working.
So I'm using Devise with Rails 3.1, and I'm making a shopping site. Visitors aren't allowed to add things to their cart unless they are signed in. This is what I'm having trouble with: if they aren't signed in, I want to redirect them to the Items index page. Here's what I have:
class ItemsController < ApplicationController
def add_to_cart
#item = Item.find(params[:id])
if current_user
#item.update_attributes(:cart_id => #current_cart.id)
redirect_to :back
else
redirect_to categories_path, notice: 'You must sign in to add an item to your cart.'
end
end
.
.
.
end
As of right now, when I click the link to add to cart, the method gets executed (I can see Rails loading and defining #item in the server log), and it reaches the 'else' statement, but no redirect happens.
I've already generated scaffolding for the index, new, etc. (all the RESTful actions). Also, I'm sure that I'm reaching the add_to_cart method because I've tried debugging with some puts statements. What's happening here?
EDIT:
Also, another weird thing which may be of use... The server seems to try to execute this method twice, and tries to 'get' categories twice:
Started GET "/items/3/add_to_cart" for 127.0.0.1 at 2012-01-12 16:53:11 -0800
Processing by ItemsController#add_to_cart as JS
Parameters: {"id"=>"3"}
Category Load (0.3ms) SELECT "categories".* FROM "categories"
Item Load (0.2ms) SELECT "items".* FROM "items" WHERE "items"."id" = $1 LIMIT 1 [["id", "3"]]
Redirected to http://localhost:3000/categories
Completed 302 Found in 26ms
Started GET "/items/3/add_to_cart" for 127.0.0.1 at 2012-01-12 16:53:11 -0800
Processing by ItemsController#add_to_cart as JS
Parameters: {"id"=>"3"}
Category Load (0.2ms) SELECT "categories".* FROM "categories"
Item Load (0.2ms) SELECT "items".* FROM "items" WHERE "items"."id" = $1 LIMIT 1 [["id", "3"]]
Redirected to http://localhost:3000/categories
Completed 302 Found in 25ms
Started GET "/categories" for 127.0.0.1 at 2012-01-12 16:53:12 -0800
Processing by CategoriesController#index as JS
Category Load (0.2ms) SELECT "categories".* FROM "categories"
CACHE (0.0ms) SELECT "categories".* FROM "categories"
Rendered categories/index.html.erb within layouts/application (0.0ms)
Completed 200 OK in 35ms (Views: 28.5ms | ActiveRecord: 4.2ms)
Started GET "/categories" for 127.0.0.1 at 2012-01-12 16:53:12 -0800
Processing by CategoriesController#index as JS
Category Load (0.2ms) SELECT "categories".* FROM "categories"
CACHE (0.0ms) SELECT "categories".* FROM "categories"
Rendered categories/index.html.erb within layouts/application (0.0ms)
Completed 200 OK in 37ms (Views: 30.6ms | ActiveRecord: 4.2ms)
EDIT 2 (as requested by Delba)
resources :items do
member do
get 'add_to_cart'
end
end
EDIT 3: changing the else statement to respond to javascript
respond_to do |format|
format.js { redirect_to items_path, notice: 'You must sign in to add an item to your cart.' }
end
For anyone who may need answers to this question, simply replace redirect_to statements with the following:
respond_to do |format|
format.js
end
Then, in your views under items, make a add_to_cart.js.erb page, consisting of javascript to make notices, or do whatever. Here's what I put in mine:
alert("Need to be signed in")
EDIT: Also, for the part where it executes twice: this is somewhat unrelated, but for some reason by default Rails includes duplicate Javascripts. Specifically, look at application.js: it says require jquery and require jquery_ujs. Disable one of these and you're home free.
To disable one of these javascripts:
Go to assets/application.js
Remove the comments (the // ) before require jquery, require tree .
This way, Rails doesn't assume the default and instead includes only jquery and whatever other javascripts you have in assets/javascripts