Displaying action partial on index page - object id doesn't persist

This problem is a continuation of an earlier thread "Partial doesn't
yet have object" but I don't think as many people saw it because my
question came up in a reply.

- I'm building an store app that include a product catalog, details
page, and cart.
- I'm attempting to put them in the same layout using partials.
- Product catalog is the index action of the store controller

Clicking on the product in the catalog invokes the "view_details"
action, which is fine if it not a partial (i.e. path in the browser is
/store/view_details/5). The problem is, according to my understanding
so far of partials, the action in "view_details" must "redirect_to
:action => :index". Because of that redirect, it appears as though the
selection doesn't persist and therefore my "view_details" (i.e. the
currently selected item) never displays.

So I'm starting to think that I have to store the current product
selected in the session by way of something like a "Basket" (more
temporary than a cart? good names are welcome) model.

Does that makes sense? Or is there a better way to make my selection
persist so I can display the catalog, deatails and cart all on the same
page?

(Yes, I'm this far behind reading the list mail, but I wanted to reply since I may still have something to add.)

I think the main problem you have right now is a misunderstanding of how layouts work.

Let's first assume your controller is named store_controller.rb. Instead of using a partial, let your method render it's default template. In the case of the view_details method in store_controller.rb, this would be app/views/store/view_details.rhtml. Rails will first render this template, save the output and then look for an optional layout for the current controller (since layouts are controller-specific).

Rails looks for the layout in the following order (see section 17.9 in Agile Web Development with Rails or section 22.9 in the second edition.)

    o Layout specified explicitly in a render command
    o Layout specified in the current controller's "layout" command
    o A layout named after the current controller, located in app/views/layouts
      (app/views/layouts/store.rhtml in your case).
    o Lastly, the file app/views/layouts/application.rhtml.

If found, the saved output of your template will replace the line in the layout body matching "<%= yield :layout %>". (Since ":layout" is the default you could just specify "<%= yield %>".) The older method, "<%= @content_for_layout %>" also works.

So, without using partials or explicit renders you would have your view_details method which would render from the following files:

app/views/store/view_details.rhtml (template for store_controller#view_details)
app/views/layouts/store.rhtml (layout file for store_controller.rb)

If you wanted a global layout for all controllers then that layout file could be:

app/views/layouts/application.rb

Now, both your template AND the selected layout can both still use partials. For example, I often have common code for the <head> section in my layout:

app/views/layouts/store.rhtml:
<html>
  <head>
    <%= render :partial => 'layouts/head' %>
  </head>
  ...
</html>

This would render app/views/layouts/_head.rhtml and place that output in the <head> section of my page.

Hope this helps,

David Schmidt

Brandon wrote: