Iterating a partial with :collection

On Fri, 2006-03-17 at 11:09 -0500, Brian V. Hughes wrote:

The error occured while evaluating nil.[]
above line 28 (I’m sort of interested to know what else is in your partial, 28
lines is a big block of lines to be iterating over) that gives you a way to see
the value. Try this:

<% session[:fac_log_test] = fac_log_test %>

Now, when the partial errors out on you, you’ll be able to view the current
value of the session, which should contain the fac_log_test value. This should
shed some light on why trying to reference it like a Hash is throwing an error.


thanks for the education in debugging…I had never thought of doing
that.

I know you’re gonna slap your forehead and say…of course - that’s what
the error message was telling us…

the session dump shows fac_log_test to be nil (not blank “”)

as for why line 28…it’s because of all the html setup code


stuff - each ‘partial’ actually becomes a fully independent ‘page’ as
there is a div with a page break at the bottom before the closing

tag as I am iterating each ‘facility’ into a separately printed
document.

your partial, before you get to line 28.


not a chance of that…the only two erb lines in the document are…
<% session[:fac_log_test] = fac_log_test %>
<%=h (fac_log_test[:facility][:name]) %>

appreciate you trying to distill the problem down for us, but I think something
might have been lost in the translation.


reasonable…I chopped the file down to a minimum (I think)

<% session[:fac_log_test] = fac_log_test %> <%=h (fac_log_test[:facility][:name]) %>

and when re-run…
NoMethodError in #
Showing app/views/reports/_fac_log_test.rhtml where line #8 raised:

You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.[]

Extracted source (around line #8):

5:
6:
7: <% session[:fac_log_test] = fac_log_test %>
8: <%=h (fac_log_test[:facility][:name]) %>

I think I have an ‘array’ of hashes which I think is different
than what is cautioned but being the newbie that I am, I am never really
quite certain which is sort of why I published the ‘debug’ at the end of
my last post.

And the debug does help. Unfortunately, what you showed us was a debug from the
instance variable that you’re passing to :collection. We’ve already discovered
that variable isn’t changing, which is why accessing it through the _counter
variable is working.


I hope that functional in a broken way doesn’t become a personal
identification for me :wink:

Iterating loops within loops over an array of hashes (with hashes in the
hashes) has been a daunting experience.

Um… wow. That would be a daunting experience, even for a very experienced
Rails developer. That level of nesting is enough to make anyone feel lost and
frustrated. It’s also one of the hardest things to debug when one portion of the
process goes awry.


the scale of my task compared with the less than a full page of
explanation within AWDWR seemed to be unequal but like everything else,
when you have to clear the forest, you start by chopping the first tree.
I have enough trees down at this point that I see a small clearing.

So I started with my best assessment on how to do this and
ultimately ended up trying every conceivable possibility just out of
frustration. Sometimes a parallel explanation using different
terminology to convey the same information clicks.

Agreed. And hopefully, we’re going to get to the bottom of why your partial
w/collection isn’t working the way partials w/collections are supposed to work…


thanks - recognize again (and I think you do) is that I am working now
by using the instance variable and the variable counter which is indeed
working and my efforts here were to obtain confirmation that things work
per documentation, possibly simplification to my code (as you can
imagine, it’s not very DRY when I have to have separate ‘partials’ for
what is essentially the same document whether I print for one specific
facility or iterate over all facilities and lastly, if I can claim
clarity of knowledge, pour forth that knowledge into something usable
for the next person.

Craig

Craig–

The reason you are getting the same responses from people is that they
are
all doing the same thing with partials from collections and it’s
working.
You haven’t said where you get your instance variable and I assumed (as
I
suspect many will) that you are working with an AR derived type. If
that’s
not the case, we may be barking up the wrong tree.

If it is an AR derived type, you should only have an array of hashes,
and if
you have associations the relationed fields will be arrays of hashes.

Please consider my recommendation of Four Days
(http://www.rubyonrails.com/media/text/Rails4Days.pdf). On about page
22, it
describes using partials to display data in a collection. It uses the
old
syntax of render_collection_of_partials, but you can map that to

render :partial => ‘some’, :collection => @thing


View this message in context:
http://www.nabble.com/iterating-a-partial-with-%3Acollection-t1289209.html#a3466020
Sent from the RubyOnRails Users forum at Nabble.com.

Just taking a wild stab at this, it appears you are throwing
does_something_with collections at a collection of collections (i.e., an
array of arrays of AR objects). Yes, the design does presume some
coupling
with the intended use. Not looking at the Rails code, I can’t say for
certain what those assumptions are. Here’s how it looks like it might
work
(if I understand your code):

def fac_log_all_test
@facility_log = facility_log_run( 1, 14 )
end

def facility_log_run number, max
results = []
number.upto(max) do |idx|
facility = Facility.find( idx )
placements = Placement.find(:all,
:conditions => [ “facility_id = ?”, idx ])
results << { :facility => facility,
:placements => placements }
end
results
end

view

<%= render :partial => ‘log_pages’, :collection => @facility_log %>

_log_pages

Page <%= log_pages_counter %>

<%= render :partial => ‘log_page’, :collection => ‘log_pages’ %>

_log_page

handles each line in the AR array returned from an individual find


View this message in context:
http://www.nabble.com/iterating-a-partial-with-%3Acollection-t1289209.html#a3466745
Sent from the RubyOnRails Users forum at Nabble.com.

On Fri, 2006-03-17 at 16:34 -0800, s.ross wrote:

end

view

<%= render :partial => ‘log_pages’, :collection => @facility_log %>

_log_pages

Page <%= log_pages_counter %>

<%= render :partial => ‘log_page’, :collection => ‘log_pages’ %>

_log_page

handles each line in the AR array returned from an individual find


I have company coming for dinner now so I will check this out and play
with the concept later tonight.

Thanks

Craig

On Fri, 2006-03-17 at 16:34 -0800, s.ross wrote:

end

view

<%= render :partial => ‘log_pages’, :collection => @facility_log %>

_log_pages

Page <%= log_pages_counter %>

<%= render :partial => ‘log_page’, :collection => ‘log_pages’ %>

_log_page

handles each line in the AR array returned from an individual find


that didn’t work at all…

NoMethodError in #
Showing app/views/reports/_log_page.rhtml where line #8 raised:

You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.[]

Extracted source (around line #8):

5:
6:
7: <%# session[:facility_log] = log_pages %>
8: <%=h (log_page[:facility][:name]) %>

just to confirm…this is what I have…

reports_controller.rb (unchanged all along)

both methods…unchanged
def fac_log_all
def fac_log_run

fac_log_all.rthml (one line)
<%= render :partial => ‘log_pages’, :collection => @facility_log %>

_log_pages.rhtml
Page <%= log_pages_counter %>

<%= session[:facility_log] = log_pages %>
<%= render :partial => ‘log_page’, :collection => ‘log_pages’ %>

_log_page.rhtml

<%# session[:facility_log] = log_pages %> <%=h (log_page[:facility][:name]) %>

Same problem…just more files.

The interesting thing to note…is that if you look above, I stored the
log_pages ‘variable’ to the session in the partial _log_pages.rhtml

When I inspected the session variables from the NoMethod error, it too
was nil. Thus if log_pages variable is nil, it can’t possibly pass
anything of value to log_page in the method that you are suggesting. In
fact, it makes sense by extension…if the calling variable is nil, no
matter how many times you call the partial, the result will still be
nil. So the attack methodology was trying to close the barn after the
horse was already gone.

Craig

On Fri, 2006-03-17 at 15:21 -0800, s.ross wrote:

Craig–

The reason you are getting the same responses from people is that they are
all doing the same thing with partials from collections and it’s working.
You haven’t said where you get your instance variable and I assumed (as I
suspect many will) that you are working with an AR derived type. If that’s
not the case, we may be barking up the wrong tree.


actually, I did provide the exact code from which I derive the instance
variable…and carried it forward for a few replies until it got in the
way and you replied to the exact message that had that code yesterday
but I will provide it again since you are claiming that I haven’t said
where the instance variable is coming from…

def fac_log_all_test
@facility_log = facility_log_run( 1, 14 )
end

def facility_log_run number, max
results = []
number.upto(max) do |idx|
facility = Facility.find( idx )
placements = Placement.find(:all,
:conditions => [ “facility_id = ?”, idx ])
results << { :facility => facility,
:placements => placements }
end
results
end

As you can see, @facility_log (my instance variable) is derived from the
method facility_log_run and is an array of hashes (facility) with
another hash inside the array of hashes (placements) and given my
understanding, this should qualify that I am working with an AR derived
type.

I also provided an excessively trimmed down version of the resultant
value of the instance variable at the moment of :render with :collection

If it is an AR derived type, you should only have an array of hashes, and if
you have associations the relationed fields will be arrays of hashes.


In a sense, yes, the ‘Facility’ model has_many :placements and it is
this relationship that comprises the internal loop or the placements has
inside the facility hash within the array that is the @facility_log
instance variable.

Please consider my recommendation of Four Days
(http://www.rubyonrails.com/media/text/Rails4Days.pdf). On about page 22, it
describes using partials to display data in a collection. It uses the old
syntax of render_collection_of_partials, but you can map that to


but once again, just like yesterday, you are telling me two things - and
I don’t dispute the validity of either of them…

1 - people are using it.
2 - look at this other example.

The issue that people are using it is something I don’t argue. But a
function that is wrapped within another function and breaks because it
is wrapped inside another function neither proves that the function
doesn’t work nor that it does work…it suggests that the function might
be fragile and possibly what is known as a bug. I am not smart enough
about these things to know that it is a bug and don’t have the toolsets
yet to figure this out.

The issue of looking at this other example is valid to a point, but I’ve
seen working examples and agree that in most instances it does work. The
instances are simplifications of model, view and controller code. Does
that mean that in more complicated multi-tiered arrays/hashes that it
will always work?

I am perfectly willing to put this to rest at this point - apparently it
depends upon the willingness of Brian H. to stay involved - as I
have stated, I have a methodology which is working and I can move
forward but it is not as the documentation says it should be and that
bothered me (and evidently bothered Dave because I gave sentiment to
that feeling with specific reference to the AWDWR book). The larger
issue that bothered me was the really scant amount of documentation to
the usage of render :partial and :collection as it does represent a
fairly sophisticated application and at the very least in my case, was
problematic but admittedly, that may be because I am not too bright.

I will quote a related thread on another list on this subject from
someone who is listed in the credits in Dave’s ‘PickAxe’ book…

“I found partials amazingly obtuse. The docs are unclear. Three or
four Rails apps later, I still keep figuring out stuff. I have a lot of
“Oh, so that’s how that’s supposed to work” moments, I think because
the code and API revolves around how one or a small number of people
just happened to have evolved the code, while observing their own
habits. So it sometimes seems that the design is not based on
well-reasoned choices to improve clarity or simplicity, but a
formalizing of the habits the developers acquired as they got used to
their own code.”

I can appreciate that few if any want to work through the issue with me
as it entirely possible if not probable that it will ultimately serve
little purpose other than to find bad code from newbie programmer at a
too large investment in time…but recognize that it may be valid for me
to believe that underlying structure that works properly in simple MVC
form can break when the application is less than simple MVC.

Craig

I think maybe the best way to proceed is to make certain the instance
variable is of the type you expect. I suggest:

<% logger.debug “hi! were in _log_page iteration #{log_page_counter}” %>
<% logger.debug “hi, again! log_page is #{log_page||‘nonexistent’} of
type
#{log_page.class}” %>

I’m just typing this out of my head, so there may be some syntax
glitches,
but if you place one of these appropriate to each of the partials as the
first line executed, the log might provide an interesting insight. In
particular, it might help us explain why you are getting a nil value.

Another thing I noticed is that you are using symbols as
og_page[:facility][:name]. Try og_page[:facility][‘name’]

I hope some of this leads down the right path.

View this message in context:
http://www.nabble.com/iterating-a-partial-with-%3Acollection-t1289209.html#a3468194
Sent from the RubyOnRails Users forum at Nabble.com.

Hi,
I tried to render partial with a collection = [{}, {}, {}].
The local variable in the partial is nil, which Craig found already
and the counter variable is stuck at 1.
I think the backward compatibility note that Craig found in the API
doc is exactly what we are trying to do here so it won’t work with
render partial.

I was able to work around it by iterating it myself and use the 2nd
partial that Steve suggested.

Cheers,
Andy

On Fri, 2006-03-17 at 21:06 -0800, s.ross wrote:

particular, it might help us explain why you are getting a nil value.


OK - it makes sense and in fact, I became highly motivated since
something broke and even though I saved my ‘working code’ separately, it
now no longer increments the @facility_log via the counter - getting
stuck as Andy Shen commented and this is something from which I have to
remove the chance element…it must have worked once and ‘cached’
results ;-( Anyone who has tracked this thread would recognize that I
am not a happy camper here.

Anyway, I think I see where you are headed with this and with some
fixes…I got this far,

Rendering reports/fac_log_all_test
hi! were in _log_pages iteration 1
hi, again! log_pages is nonexistent of type
NilClass
hi! were in _log_page iteration 0
hi, again! log_page is log_pages of type
String

ActionView::TemplateError (You have a nil object when you didn’t expect
it!
You might have expected an instance of Array.
The error occured while evaluating nil.[]) on line #11 of
app/views/reports/_log_page.rhtml:
8:
9:
10: <%# session[:facility_log] = log_pages %>
11: <%=h (log_page[:facility][:name]) %>

which suggests to me that the ‘counter’ of fac_log_all_test is stuck
before the data gets through to _log_pages and I can’t explain why it
doesn’t show iteration 0 for _log_pages but starts at iteration 1

Another thing I noticed is that you are using symbols as
og_page[:facility][:name]. Try og_page[:facility][‘name’]

I hope some of this leads down the right path.


I think I’m dead before it get’s this far, but changing the symbol
[:name] to ['name] on line 11 per above made no difference.

Thanks

Craig

On Sun, 2006-03-19 at 06:58 +0000, Justin F. wrote:

focused example to discuss on the list. (Also, if you are not already in

Earlier in this thread you wrote:

I’d like to reinforce the advice others have given you. The definitive
documentation is the API RDoc. I was impressed when I first followed
“Four Days on Rails” about a year ago with the way it introduced each
feature and then showed where to look in the API documentation for more
information. And while AWDR was published before Rails reached 1.0, the
core team committed to retain compatibility with the book.


yes, yes and yes…

I have it all figured out and I will sort through it all tomorrow and
get a wiki page up in the next few days.

The issue though isn’t html code in partials, which of course is butt
ugly and this report is intended to be a multi-page print and there are
css page breaks, etc.

The issue is simply the methodology of a complicated array of hashes
within hashes and render :partial :collection just can’t deal with that.

I ended up putting all of the code in a class and simply looping within
the view code…it’s clean it’s neat it works and it avoids
render :partial :collection which clearly works in simple cases and
simply gags in multi-tiered arrays/hashes.

I think that is why most experienced programmers haven’t run into this
before…because they were already putting methods in their models that
created the containers of data as objects where in my linear thinking, I
tried to just accumulate all the data in a massive array in the
controller and have view code sort it all out. I hope that makes sense
to others as it seems to make sense to me. I have no experience with
object oriented programming and it showed here.

Thanks

Craig

Craig W. wrote:

On Sun, 2006-03-19 at 06:58 +0000, Justin F. wrote:
[…]

<%=h (log_page[:facility][:name]) %>
stuff - each ‘partial’ actually becomes a fully independent ‘page’ as
feature and then showed where to look in the API documentation for more
ugly and this report is intended to be a multi-page print and there are
css page breaks, etc.

It does sound as if you are confusing HTML pages (more accurately,
HTML documents) with printed pages. Your HTML response must only contain
one element. CSS page breaks give some control over how it is
rendered for print.

The issue is simply the methodology of a complicated array of hashes
within hashes and render :partial :collection just can’t deal with that.

You appear to still believe that you ran into a bug in Rails. Try to
develop a minimal demonstration of this, and then if you are still
convinced there is something wrong, discuss it again.

I ended up putting all of the code in a class and simply looping within
the view code…it’s clean it’s neat it works and it avoids
render :partial :collection which clearly works in simple cases and
simply gags in multi-tiered arrays/hashes.

Please demonstrate this rather than continuing to assert it without
supporting evidence.

I think that is why most experienced programmers haven’t run into this
before…because they were already putting methods in their models that
created the containers of data as objects where in my linear thinking, I
tried to just accumulate all the data in a massive array in the
controller and have view code sort it all out. I hope that makes sense
to others as it seems to make sense to me. I have no experience with
object oriented programming and it showed here.

Don’t forget that the arrays and hashes you were using are objects too.

regards

Justin

Craig,

Two points:

  1. Learn how to use a feature on a trivial example before trying to
    weave its use into your apparently complex application. I suggest you
    keep a separate ‘sandbox’ Rails application for trying things out. Had
    you done this, you should have arrived at the correct understanding of
    the AWDR description of partials before getting bogged down in their use
    in your application - or, failing that, you would have had a small
    focused example to discuss on the list. (Also, if you are not already in
    the habit, use irb to try out Ruby features and use script/console to
    test fragments of intended controller functionality against your
    models.)

  2. How on earth can you have all this HTML boilerplate in a partial?

You can put all the non-content stuff in a layout, so your view gets
spliced in inside the HTML body, and your partial will then get spliced
in at the appropriate point within the view.

Earlier in this thread you wrote:

as for why line 28…it’s because of all the html setup code

tags>
> stuff - each 'partial' actually becomes a fully independent 'page' as > there is a div with a page break at the bottom before the closing > tag as I am iterating each 'facility' into a separately printed > document.

What does this mean? What are you expecting to return to the browser?
Are you confusing HTML pages with printed pages?

I’d like to reinforce the advice others have given you. The definitive
documentation is the API RDoc. I was impressed when I first followed
“Four Days on Rails” about a year ago with the way it introduced each
feature and then showed where to look in the API documentation for more
information. And while AWDR was published before Rails reached 1.0, the
core team committed to retain compatibility with the book.

regards

Justin

On Sun, 2006-03-19 at 14:36 +0000, Justin F. wrote:

I’d like to reinforce the advice others have given you. The definitive
get a wiki page up in the next few days.
The issue is simply the methodology of a complicated array of hashes

Don’t forget that the arrays and hashes you were using are objects too.


OK - at some point, I will try to create some exhibition type structure
for someone to use to examine my contention but that is no simple task
and given the incredible amount of wasted hours that I have on this, I
am so far behind in real work that it is going to wait simply out of
necessity.

Craig