Reputation: 6193
I want to an ajax request to call user
controller's xyz
action with the passed parameter stage
and then append it on #the_box
so that I can perform conditional operation like for stage x
append @user.age
, for stage y
append @user.age+1
and for stage z
append @user.age-1
. How should I do?
I have a html.erb file contains such code:
<center>
<%= link_to "A", xyz_user_path, stage: "x", remote: true %>
<%= link_to "B", xyz_user_path, stage: "y", remote: true %>
<%= link_to "C", xyz_user_path, stage: "z", remote: true %>
</center>
<div id="the_box"></div>
and users_controller.rb
has
before_action :set_user, only: [ :xyz]
def xyz
respond_to do |format|
format.js {}
end
end
private
def set_user
@user = User.find(params[:id])
end
and this xyz.js.erb
is what I have now but cannot deal with parameter so it cannot handle conditional operation
$("#the_box").append("<%= @user.age%>");
Upvotes: 2
Views: 5360
Reputation: 1439
Here I'm going to access an instance variable defined in wish_me action.
controllers/jserb_controller.rb code:
class JserbController < ApplicationController
def index
end
def wish_me
@test = 'Hi how are you?'
respond_to do |format|
format.js
end
end
end
/views/jserb/index.html.erb code:
<div class="wish-me"></div>
<%= link_to "Wish Me", wishme_path, remote: true %>
/views/jserb/wish_me.js.erb
$(".wish-me").append("<%=j @test %>");
config/routes.rb code:
match '/index' => 'jserb#index'
match '/wishme' => 'jserb#wish_me', :as => :wishme
Now try to hit http://<domain-name>/index
and then click on WishMe
link. So now you are able to pass instance variable to js.erb and accessed the same.
Upvotes: 0
Reputation: 76774
The other answers will help you on here - let me explain them
format.js
When you use format.js
to filter the mime types
, opening brackets basically tells Rails that you want to perform some custom functionality (and hence it won't load the [action].js.erb
as default)
If you want to just invoke [action].js.erb
, you'll have to call the following:
respond_to do |format|
format.js #-> will just call [action].js.erb
end
You'll want to read up more about Rails mime types (how to determine XHR requests) & the respond_to
block
@instance_variables
Secondly, you need to consider the role of @instance variables
in your application, and consequently, the method in question.
The main issue you have is you're calling @user
in a method which doesn't define it - hence you'll likely see the error undefined method ___ for nil:NilClass
or similar
You must remember that Rails is just a gem - a series of classes which runs on the Ruby language. This means that each time you wish to perform a method on an "object" / piece of data, you'll have you to declare / create the object in your Rails application:
def xyz
@user = User.find params[:id] #-> sets the variable for the duration of the "instance"
...
end
Please take note of the name of the variable -- an instance variable. By setting @user
(instance variables are always defined with an @
), you basically give Rails the ability to access the data inside it for as long as the class which defines the variable is invoked.
Basically means that if you set @user = User.find
, it will be available through your view
& other helper methods called from the instance of the class
Fix
Finally, to address your question directly:
I want to an ajax request to call user controller's xyz action with the passed parameter stage and then append it on #the_box so that I can perform conditional operation like for stage x append @user.age, for stage y append @user.age+1 and for stage z append @user.age-1. How should I do?
#config/routes.rb
resources :users do
get "xyz/:stage" #-> domain.com/users/:user_id/xyz/:stage
end
#app/views/users/your_view.html.erb
<% links = [["A", "x"], ["B", "y"], ["C", "z"]] %>
<% links.each do |link, stage| %>
<%= link_to link, xyz_user_path(user, stage: stage), remote: true %>
<% end %>
#app/controllers/users_controller.rb
Class UsersController < ApplicationController
def xyz
case params[:stage]
when "x"
@user.increment!(:age)
when "y"
@user.decrement!(:age)
end
respond_to do |format|
format.js
end
end
end
#app/views/users/xyz.js.erb
$("#the_box").append("<%=j @user.age %>");
Upvotes: 6
Reputation: 6029
You should pass the parameter in the helper like this:
xyz_user_path(stage: "x")
And then in your js.erb you can access it like:
<%= params['stage'] %>
Upvotes: 0