Should you only use local variables in a partial? - ruby-on-rails

Using local variables seems advisable in a partial that could be used application-wide to avoid dependencies across the application.
But within a single controller it seems acceptable to reference instance variables that you know will be available in all of the actions that use the partial.
If you do this, there seems to be a risk, however, that a particular action may get changed to no longer provide the instance variable to its view. Then the partial would stop working. I'm not sure if this is really a problem, though, since a regular view would encounter the same risk.
Does it matter if you reference instance variables in a partial?

You're on a roll today! :-)
You can pass variables into the partial as :locals to keep this all nice and clean. For example,
render :partial => 'my_partial', :locals => { :some_variable => some_variable, :some_important_value => 'an important point!' }
These variables are then available in the partial view:
<%= some_variable %>
<%= some_important_value %>
However, there is nothing specifically wrong with using instance variables in your partials.

i would only recommend using instance variables as long as the partial is not shared, since this can get confusing very fast ;)

Related

Rails 3.1 partial fallback

I don't quite understand why the new feature of partial rendering doesn't always kick in.
For example with this code:
= render(:partial => "pages/#{foo}/data")
it will never fallback to the partial pages/_data.html.erb if pages/test/_data.html.erb doesn't exist. How can I get this behavior?
Something you can do is :
= render(:partial => "pages/#{foo}/data") rescue render(:partial => "pages/data")
But I would be interested if someone has a better solution, this one is not elegant especially when you have some variables to pass to the partial. At least It can be better if handled by a helper.
My understanding of partials is not that they are small, standalone chunks of HTML to render, but rather bits and pieces of abstraction that you can use to organize your code in a more coherent manner.
As I see it, partials are created to be used in one or more places such that the file does not become cluttered, they're not used to simply be rendered by themselves. I could be mistaken, however.

Passing from using '#user' to using 'user' in 'html.erb' files: how and why?

I am using Ruby on Rails 3 and I was advised (#user is a global variable, you can't 'localize' it. I would suggest passing local variables from your controller in the same way.) to use variables like user instead of #user in view files. Why to do that, exactly?.
So, I am considering pass from using #user to using user. That is, (in html.erb file) from using
#user.name
to using
user.name
At this time, for example, in the show method of my controller I have:
def show
#user = Users.find(1)
...
end
What I have to change in the controller to do that works in views?
This is only something you need to worry about when the same partial is called in the views from more than one controller.
Having a partial that is using #user in it (likely set in a users_controller), means that the moment you call that partial in a view from some other controller (for example; accounts_controller) that does not set #users you will get an error. If you reference only local variables in your partial you can set them as needed from any controller with the :locals hash that was described.
That's non sense, only instance_variables are sent from the controller to the view.
Nikita Rybak was not wrong in his answer, he just passed the instance variable contained in his view (#current_user) to a partial where it has a different name (user):
:locals => { :user => #current_user }
he concluded very well:
Local variables are local, so you don't need # to refer them.
Indeed you have two choices when working with a partial:
assume it has access to the instance variable (which is not advised)
pass the instance variable to the partial with a local name which is the Rails' way
Take a look at this Rails Best Practice. Using local variables is preferable way when rendering partials (those view files which start with a _). That's because you'll need review your controller's code to know about instance variable.

Is is possible to include views in a gem that the user can render as a partial?

Say I am making gem "awesome_o" and it will make apps awesome. How could I package up some view partials so that the user can optionally use them in his/her app for eg:
<%= render :partial => '#{some_path_to_awesome_o}/list_of_awesome' %>
Is that possible?
As I understand it, if you create an app/views directory in the base of your gem, Rails adds that to the views load path. So, create your partial at app/views/my_gem/my_partial.html.ext, and then render :partial => 'my_gem/my_partial' should work as expected.
As far as usage goes, though, I'd like you to include a simple helper method, too, since it'd be far easier for me to use and would allow you to change exact implementation later on. Even if it just calls render :partial internally, it'd produce a smoother experience.
Nowadays you could use an engine: http://edgeguides.rubyonrails.org/engines.html
As an alternative you could also make generators to create the views in the rails app, this would allow the users to alter the views to suit their needs.
I guess it depends on exactly what you are doing.

Rendering an RJS of controller A in context of controller B

This has been asked before, but didn't receive a proper answer:
I have a User that has Files. When a File is updated (via AJAX) I want to refresh the User view.
I do this in RJS:
page['user'].replace_html :partial => 'users/user'
However, the _user.erb.html partial references other partials in the users directory, and e.g. for _name.erb.html Rails complains it can't find the template Files/name. (I want it to look for Users/name).
Is there a way to change the context of the view rendering to that of controller Users? I'd hate to fully-qualify all of the partial rendering requests.
Maybe try moving the _user.html.erb partial to a 'shared' folder? So the RJS would become:
page['user'].replace_html :partial => 'shared/user'
See http://api.rubyonrails.org/classes/ActionView/Partials.html - a local variable may also need to be defined.

How to use in_place_edit plugin for rails with partials?

I am using the "in_place_editing" plugin for rails to render a form with in-place edits. Thing work fine as long as the default template is chosen by rails (no 'render' method is invoked inside the controller), but they break down when I try to render a partial using "render :partial => 'partial_name'" call. Is this a known issue (in_place_edit does not work with partials?) or am I missing something? I am getting the following error while rendering the partial:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
.../vendor/plugins/in_place_editing/lib/in_place_macros_helper.rb:74:in `in_place_editor_field'
You don't provide anywhere near enough information in your question, giving only two lines of the backtrace and no fragments of the view which does work, or the partial which does not. This means that any attempts to answer you must be based largely on guesswork. That said, the in-place editor helper is just a helper method like any other, nothing special. You can call it from just about any view component. It is highly likely that the way in which that view is included by the controller, or indeed a parent view, is not the reason it is failing.
The helper method is complaining about a nil value. This means that most likely, your partial is invoking in_place_editor_field and passing it values which are not defined in the partial. Check to make sure it isn't using local variables which are not defined, compared to those used in the view where your in_place_editor_field call works; check to make sure that it isn't asking for different instance variables too. In all probability you'll find the views which work are using one variable name while the partial you've tried to render is using another.
The render :partial => ... mechanism supports different ways of explicitly passing in values to the partial; you may choose to use these to clarify your code. See the :locals and :object options for the "Rendering partials" section of the render documentation in the Rails API at:
http://api.rubyonrails.org/classes/ActionController/Base.html#M000658
I am working on a maintenance project which is in rails 2.3.8. And this issue ate a lot of my time
In the view, Change the view to have an instance variable:
#batch = batch
in_place_editor_field :batch, 'priority'

Resources