New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

partial render failed when rename a local variable use "as:" #26286

Closed
hwy801207 opened this Issue Aug 26, 2016 · 8 comments

Comments

Projects
None yet
5 participants
@hwy801207

hwy801207 commented Aug 26, 2016

partial render failed when use "as:" to rename a local variable
like this
<%= render partial: "product", as: "item" %>
at the page http://guides.rubyonrails.org/action_view_overview.html

the error message is
undefined local variable or method `item' for #<#Class:0x000000053dc200:0x007fd688a25740>

when change to
<%= render partial: "product", object: product, as: "item" %>
it's ok

rails version 5.0.1
ruby version 2.3.0

@aaronang

This comment has been minimized.

Contributor

aaronang commented Aug 26, 2016

@hwy801207 I had a quick look at your problem and I can confirm the same problem occurs with Rails version 5.0.0.1. As far as I know there exists no Rails version 5.0.1. I assume it is a typo?

To reproduce these steps I have quickly created a Rails 5.0.0.1 project, which can be found here: view_locals_as.zip. Just run rails s and go to localhost:3000/products/index and you will see the error.

PS. I am quite new to Rails and if there are better ways to create reproducible steps for problems related to rendering, I would gladly receive feedback on how to improve.

@maclover7

This comment has been minimized.

Member

maclover7 commented Aug 26, 2016

Hi all,

  • @hwy801207: Thank you for reporting this documentation error! Can you please update the documentation to add in the object: key, to what we are passing to the render method?
  • @aaronang: Good work on your first reproduction app! In the future, if you'd like, feel free to use any of Rails' "bug report templates", which are available here.

Best recourse here is to update the documentation.

@aaronang

This comment has been minimized.

Contributor

aaronang commented Aug 26, 2016

@maclover7 Thank you for your reply! I was just wondering if you could provide me an example of how one of these templates can be used to reproduce rendering-related problems. In specific, how would such reproducible example look like for rendering partials?

@prakashmurthy

This comment has been minimized.

Contributor

prakashmurthy commented Aug 26, 2016

Looks like bef9484 changed the earlier behavior and made the following part of the documentation outdated:

By default ActionView::Partials::PartialRenderer has its object in a local variable with the same name as the template.

@nygrenh: I don't agree with the statement in your commit message that the behavior is not as intended. I think the documented behavior is useful and should be reverted back. Please let me know if there are any other considerations in removing the default object in ActionView::Partials::PartialRenderer.

@nygrenh

This comment has been minimized.

Contributor

nygrenh commented Aug 26, 2016

@prakashmurthy The commit you mentioned should not affect the behaviour of actual local variables. All it does it removes extra values from the local_assigns hash in a case when there is no local variable with the same name defined inside the partial. As far as I know the local_assigns hash does not affect what local variables will be defined defined in the view. As the commit does not undefine any local variables, I do not see how this change could cause the problem.

Here's the documentation for the local_assigns hash:

The local variables passed to sub templates can be accessed as a hash using the local_assigns hash. This lets you access the variables as:

Headline: <%= local_assigns[:headline] %>

This is useful in cases where you aren't sure if the local variable has been assigned. Alternatively, you could also use defined? headline to first check if the variable has been assigned before using it.

As why this change was made, it is related to the solution of the locals problem that is blocking #19272. Basically, the reason is that if we want to have a precompiled template that can be used no matter what local variable combination the template is being rendered with, we need to access all passed local variables through the local_assigns hash. So naturally having extra stuff in that hash would cause our heuristics to think a variable is defined even though it is not.

TL;DR: No, bef9484 was never intended to do that and I don't think it caused this issue.

@prakashmurthy

This comment has been minimized.

Contributor

prakashmurthy commented Aug 26, 2016

Thanks @nygrenh for the detailed response. I guess I read too much into the commit message details.

Let me check further why the defaults are coming up nil / render partial: "post" is failing with undefined local variable or method 'post' error message.

@prakashmurthy

This comment has been minimized.

Contributor

prakashmurthy commented Sep 2, 2016

Haven't been able to devote enough time to work on this issue; won't be able to get back to this soon.

Here is the summary of what I have found so far, should anyone else wants to take up the task of fixing this:
The behavior documented in the guides (in the attached image below) work fine in Rails versions <= 3.2.x, and do not work in Rails 4.x and 5.x.

view_default_local_variable

In Rails 3.x versions, by the time this line is hit, the instance variable with the same name as the partial is included in the locals variable from @variable to as to object to locals[as].

@maclover7

This comment has been minimized.

Member

maclover7 commented Sep 13, 2016

PR to update the docs has been merged, going to close this issue out.

@maclover7 maclover7 closed this Sep 13, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment