In my application I call the controller foo that sets a variable var to a value and then want to render the the div container with id bar_var. Therefore I have a js.erb file with the code
$('#bar_var').html("<%= escape_javascript(render :partial => ....)
How can I pass the variable parameter var to differ between container bar_1 and bar_2 perhaps? The bar parameter is passed via get parameters and also via ruby class variables.
As far as your question is kind of unclear I will suggest this
$('#bar_<%= params[:var] %>').html("<%= escape_javascript(render :partial => ....)
Related
I'm adding a new partial view in ruby on rails project and want to pass some additional data to the partial. I have code below for rendering a view . I understand this is the way to pass data (id in my case) to partial view. I'm not sure if this is the best way, as I'm new to rubyonrails. How do i access in my partial view file?
render "index" , :locals => {:id => params[:id]}
You can pass data to your view(s) using options on render, one of which is locals, or by setting instance variables which automatically propagate.
Normally what's done is something like this:
#id_param = params[:id]
Where within your view you can use #id_param wherever and whenever:
<%= #id_param %>
I've chosen #id_param for a name here instead of #id to give it a bit more context as #id on its own might prompt questions of "What ID?"
If you want to do the locals method, then:
render 'index', locals: { id: params[:id] }
Using the Ruby 1.9 hash notation for simplicity here, versus the outdated 1.8 style in your original example. This produces a local variable called id that can be used in that view, like:
<%= id %>
I realize this is similar to some other questions, but I have been through a fair number of those and I think I'm doing what they suggested, but my code is still not working.
So, as the title says, I'm attempting to load a partial from a js.erb file (in response to an AJAX call.) However, it is not working correctly.
full_list.html.haml:
=link_to(test_path(#work), id: "privacy-button", remote: true) do
= render "privacy_button_content", locals: {:show_others => #work.show_others}
_privacy_button_content.html.haml:
-if locals[:show_others] == false
-test_string = "twas false"
-else
-test_string = "twas true"
%p = test_string
works_controller.rb:
def test_function
#work.model_function
respond_with(:layout => false)
end
test_function.js.erb:
$("#privacy-button").html("<%= escape_javascript render(:partial => 'privacy_button_content', locals: {:show_others => #work.show_others}) %>");
So the full_list has privacy_button, which is rendering the partial, and the response to clicking the #privacy-button should be to modify something in the controller, and get the response.js.erb.
This works correctly on page load (so passing the local to the partial does work,) but whenever I run the AJAX call I'm getting
(undefined local variable or method `locals' for #<#<Class:0x00000005006338>:0x000000068481f8>):
Any help would be appreciated.
Update _privacy_button_content.html.haml as below:
-if show_others == false
-test_string = "twas false"
-else
-test_string = "twas true"
%p = test_string
When you pass show_others in locals hash, a local variable would be created for you named show_others. You can access it as show_others in the partial and not locals[:show_others].
Refer to Passing local variables in Rails Guides.
Apply Kirti Thorat's change and then change
= render "privacy_button_content", locals: {:show_others => #work.show_others}
for
= render "privacy_button_content", show_others: #work.show_others
Also remember that views should not have logic, it should be in a helper or in a decorator
BTW: I think %p = test_string should be %p= test_string
So, I've figured it out. It seems that specific error I was getting had to do with the render syntax when working when haml (I got the same issue when I specified render :partial from the view, so it wasn't unique to the js.erb.)
The code in partial.js.erb now looks like:
$("#privacy-button").html("<%= escape_javascript render("privacy_button_content", :locals => {:show_others => #work.show_others}) %>");
As you can see, the main difference is having render "works_group_list" rather than render( partial: => "works_group_list". As I said, I believe this may be related to my views being written in Haml, though it should be noted that the render(partial:...) syntax does work when not attempting to pass local variables from a js.erb.
I was also getting some little issues because I kept referring to something as #my_element in the js when in the html it was #my-element. So if you're encountering this issue, checking your spelling (for the thirtieth time) never hurts.
Edit:
Just a note, as others have pointed out using the locals hash is not mandatory. So the line of code could instead be
$("#privacy-button").html("<%= escape_javascript render("privacy_button_content", :show_others => #work.show_others ) %>");
This will work as long as you update your partial appropriately (referring to var instead of locals[:var]).
I'm trying to pass some locals into a partial render in rails, however they are not getting passed.
<%=render :partial => "search_results", :locals => {:refinement => "all", :query => params[:search]}%>
The partial is being rendered in a view that has the param[:search] in it, that params[:search] is accessable inside of the partial without it being passed in as a local.
I'm trying to access the locals refinement and query by doing params[:refinement] and params[:query] inside of the partial, however they are not being recognized.
You don't access them via params - you just access the local variable, eg. refinement or query.
Access them as locals[:refinement] or locals[:query] inside your partial. That should work.
When seeing in the code the following lines :
<%= render :partial => 'ingredients/form',
:locals => {:form => recipe_form} %>
I wonder what is actually happening.
I have noticed render is a part of RenderingHelper. How do I know which object I can use while writing? How can I use it without RenderingHelper prefix as in Java (i.e. RenderingHelper.render). Am I inheriting from it in the form view?
Since I know Java and C#, I have searched for ingredients/form and couldn't find it in the code. I am guessing it is part of the convention over configuration rule. What is it? Where is it defined?
Regarding the :locals => {:form => recipe_form} line, is that a parameter sent to render? Is that double assignment? What does the => operator actually do here?
If it is a parameter it was hard to understand from the render signature:
Returns the result of a render that's dictated by the options hash. The primary options are:
:partial - See ActionView::PartialRenderer.
:file - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
:inline - Renders an inline template similar to how it's done in the controller.
:text - Renders the text passed in out.
In the future, please try to ask one question per post.
RenderingHelper is a module, and its methods are made available via an include somewhere. Read more about how Ruby's modules work.
Partial filenames are always prfixied with an underscore, your partial will be located in app/views/ingredients/_form.html.erb
Both :form and :locals are keys in an options hash being passed to render; The corrpsponding value for :locals is a nested hash, which contains one key, :form whose value is a local variable named recipe_form. This might be more obvious if you explicitly specify some of the optional punctuation:
<%= render({:partial => 'ingredients/form', :locals => {:form => recipe_form}}) %>
Ruby (and Rails specifically) use variable length lists of arguments in the form of key/value hashes. They aren't hard to use or understand at all once you understand the basic syntax
2. "ingredients/form" isn't code--it's a string. It refers to the _form partial for the ingredient model. It's located in app/views/ingredients/_form.erb.html.
3. :locals => { ... } means the render function is getting a map entry with the symbol :locals as its key. render knows what to do with that map.
It's not "double assignment", it's that the value of the :locals key is also a map. =>, or the "hash rocket", is Ruby 1.8/1.9 syntax for assigning a map value to a map key. In Ruby 1.9 you can use a shortcut, locals: { ... }.
(IMO which is more readable depends on the values--when the values are keys, I think the new syntax is heinous, otherwise I like it.)
4. How is the signature difficult to understand? The argument is a hash of options.
It seems that setting multiple instance variables in a controller's action (method) causes problems in the template, only the very first instance variable got passed to the template. Is there any way to pass multiple variables to the template? Thanks! And why, in Ruby's perspective, does the template get access to the instance variables in an action?
You might also want to look into the :locals option of render. Which accepts a hash such that keys are symbols that map to local variable names in your template, and the values are the values to set those local variables to.
Example:
render "show", :locals => {:user => User.first, :some_other_variable => "Value"}
and this template
User ID: <%= user.id %><br>
Some Other Variable: <%=some_other_variable%>
will produce:
User ID: 1<br>
Some Other Variable: Value
When you're reusing partials across multiple controllers. Setting local variables with the :locals option is simpler and much more DRY than using instance variables.
you shouldn't have any problem setting multiple instance variables. For example:
class CarsController < ApplicationController
def show
#car = Car.find(:first)
#category = Category.find(:first)
end
end
will allow you to access both #car and #category in cars/show.html.erb
The reason this works is nothing inherent to ruby, but some magic built into rails. Rails automatically makes any instance variable set in a controller action available to the corresponding view.