3

This should be extremely straightforward and well documented, and I've done it several times, although there's something that's still killing me.

I have a structure of partials calling nested partials.

At some point one render call needs to pass an extra variable to the partial, although the rendering of the partial fails with a:

undefined local variable or method `<variable name>' for #<#<Class:....>

Here's my code for calling the render:

= f.simple_fields_for :orders do |c|
  = render partial: "fields", locals: {f: c, step: f.object.step}

though this doesn't work either:

= f.simple_fields_for :orders do |c|
  = render "fields", f: c, step: f.object.step

here's where the exception is raised:

f.input :quantity, input_html: {step: step}

the form_for comes from the views/lists/_form.html.haml:

= simple_form_for( @order, :html => { :multipart => true }, defaults: { input_html: { class: 'input-medium' } } ) do |f|

f is then passed to views/orders/_order_forms.html via

= render "orders/order_forms", f: f

here's the exception with trace:

    ActionView::Template::Error (undefined local variable or method `step' for #<#<Class:0x007fe0479ba2b0>:0x007fe04256a930>):

application trace:
    app/views/orders/_fields.html.haml:9:in `_app_views_orders__fields_html_haml___1860431911739668171_70300581339300'
    app/views/orders/_order_forms.html.haml:30:in `_app_views_orders__order_forms_html_haml__2241963939037094859_70300612771460'
    app/views/lists/_form.html.haml:48:in `block in _app_views_lists__form_html_haml__1669043093238943449_70300583658680'
    app/views/lists/_form.html.haml:3:in `_app_views_lists__form_html_haml__1669043093238943449_70300583658680'
    app/views/lists/new.html.erb:3:in `_app_views_lists_new_html_erb___1563391577928218041_70300593681100'
    app/controllers/lists_controller.rb:67:in `new'

framework trace (the end of it):

actionpack (3.2.8) lib/action_view/template.rb:145:in `block in render'
activesupport (3.2.8) lib/active_support/notifications.rb:125:in `instrument'
actionpack (3.2.8) lib/action_view/template.rb:143:in `render'
actionpack (3.2.8) lib/action_view/renderer/partial_renderer.rb:265:in `render_partial'
actionpack (3.2.8) lib/action_view/renderer/partial_renderer.rb:238:in `block in render'
actionpack (3.2.8) lib/action_view/renderer/abstract_renderer.rb:38:in `block in instrument'
activesupport (3.2.8) lib/active_support/notifications.rb:123:in `block in instrument'
activesupport (3.2.8) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (3.2.8) lib/active_support/notifications.rb:123:in `instrument'
actionpack (3.2.8) lib/action_view/renderer/abstract_renderer.rb:38:in `instrument'
actionpack (3.2.8) lib/action_view/renderer/partial_renderer.rb:237:in `render'
actionpack (3.2.8) lib/action_view/renderer/renderer.rb:41:in `render_partial'
actionpack (3.2.8) lib/action_view/helpers/rendering_helper.rb:27:in `render'
haml (4.0.3) lib/haml/helpers/action_view_mods.rb:10:in `block in render_with_haml'
haml (4.0.3) lib/haml/helpers.rb:89:in `non_haml'
haml (4.0.3) lib/haml/helpers/action_view_mods.rb:10:in `render_with_haml'
cocoon (1.2.0) lib/cocoon/view_helpers.rb:40:in `block in render_association'

I've had a similar issue before and I resolved it in simplifying the passing of locals.. but now I would really like to understand what's going on.

any clue?

I'm using:

ruby 2.0.0p297
rails 3.2.8

Thanks a lot in advance..

UPDATE

I have debugged my view and figured that the order_forms is being rendered twice, the first time step is not set, while in the second rendering it is set correctly.

I'm not sure why this happens, but I managed to work it around with adding the following line to my fields.html.haml.

-step = step || 1

basically I put a default value to step, in case it's not defined, so that at the first execution the rendering doesn't crash, while at the second execution it works properly.

The page looks as expected now. Although I'm thinking about the waste of resources when rendering the stuff twice.

any idea on why that happens?

4

1 回答 1

4

在发现代码运行了两次之后,我开始调查还有谁在运行它。

我意识到在调用茧函数之前只有几行link_to_add_association

当然,不仅是官方render渲染部分,还有那个函数需要渲染它。

我已经添加了这一行:

:render_options => {:locals => {:step => step }},

到我的link_to_add_association函数调用并删除了解决方法,现在一切都按预期工作。

与此类似的更现代的版本是:

render_options: {locals: {step: step }},

短一点,看起来更好。

于 2013-08-25T15:51:32.163 回答