开发者

Helper method does not update a Controllers instance variable

I define an instance_variable in my Pages Controller and initialize it with some string.

I include that instance_variable in a page.

It shows up.

Great!

If my page includes some _header layout, which uses a Pages Helper method which updates that instance_variable, my page shows the original and not the updated string.

Logs show that the _header was rendered before the page, so it did called a Pagers Helper method that updates that instance_variable BEFORE it has rendered my page.

So why does that page not include the updated string?

Im new to RoR, trying to understand how it works.

Thanks in advance!

EDIT:

W开发者_如何转开发ell. Even if the rails server log show, that the yield ed page has been rendered after the render ed pages... It looks like it has been rendered before them.

If I change an instance_variable in the first render ed page, the changed value is available in all following render ed pages, but unchanged in the yield ed page, even if the yield lays inbetween render 's(in application.html.erb), and the rails server logs show even that is has been render as the last.

EDIT:

For some reason I user the word 'layouts' where I would had to use the word 'partials'.


The instance variables are copied, not shared, between objects. In a view a new variables are created with the same names, and 'pointing' to the same object which was referenced by the variables in the controller. So, if you assign a new value to a variable in a view, other objects will not know about the change.

But if you really need to change an object referenced by some variable, modify that object instead of assigning a new one to a variable. An example will tell you what I mean.

@var = "a new string" # it creates a new String object.
@var.replace "a modified string" # it changes the content of the object.

If you use a 'replace' method (String objects have such method) then your controller may see the change. If you just assign a new object to a variable, your controller will not see the change. But don't trust me too much, as I usually don't modify the objects in a view. Just test it.


I was curious about this as well, so I wanted to see the "order of processing". This is the result of that test. It clarified things for me... hopefully it answers the question even if doesn't solve the problem. All views are in haml. Pardon the extraneous code i.e. %br. I was going for clarity over brevity.

Controller:

@test = 1

Helper:

def change_test
  @test += 1
end

Application Layout:

!!!
%html
  %body
    Application Layout Pre-change = 
    = @test
    %br
    Application Layout Change = 
    = change_test()
    %br    
    = yield

Yielded View:

%br
Pre-Header = 
= @test
%br
Pre Header change = 
= change_test()
%br
= render "test_header"
%br
Yeilded page Pre-change = 
=@test 
%br
Yeilded Page Change = 
= change_test()
%br
= render "test_footer"
%br

Header Partial:

%br
Header Pre-change = 
= @test
%br
Header change = 
= change_test()
%br

Footer Partial:

%br
Footer Pre-change = 
= @test
%br
Footer change = 
= change_test()
%br

Output:

Application Layout Pre-change = 5 
Application Layout Change = 6 

Pre-Header = 1 
Pre Header change = 2 

Header Pre-change = 2 
Header change = 3 

Yeilded page Pre-change = 3 
Yeilded Page Change = 4 

Footer Pre-change = 4 
Footer change = 5 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜