Multiple Controllers and Models in One View

My application has Account Status -> Upgrade account page that
displays account model and billing_profile model. There is also
another page Account Status -> Billing Profile that displays only
billing profile.

Now, my question is how do I display both the account and billing
profile models in my view? TIA.

Hi Bala,

please paste some code, it’s hard to find your problem this way…

I was reviewing the AWDWR book, there is a section that shows how to
use multiple models in one view. I will use the fields_for and see if
I still have any problems.

The problem is that you cannot have multiple form tags in one view.
This happens when you want to use more than one model in a view.
Thanks.

Can you not use partial templates for this?

My site has a main page and the various areas are populated by code from
different controllers.

This was the biggest thing that was not obvious from reading the Agile
book. It took me a bit of experimenting to figure it out but now I have
a good foundation that I’m building my sites on :slight_smile:

So John - can you provide some background on how you solved this
problem? Having been all the way through AWDWR, I have found no “best
practice” for this problem mentioned anywhere in the book, nor by
searching on the web. I think this is one of those Rails things that
some people just “get” and others swirl around and bang into for a bit
until they “get it”. Your response will be helpful to all of us in
the latter group! :wink:

Hi, yes I’ll try.

I bought the AWDWR and Pickaxe books. I worked through every step of the
“depot” tutorial and then set to putting a small application together.

The first thing I did was to write a simple user login module (I know
these are available but I wanted to do it as a learning exercise). It
has a very simple view that either displays a username/password login
form or a logged in status with a logout button.

I then designed a simple header/footer, body and sidebar layout and I
wanted to put my authentication view in the sidebar and have whatever
content I needed displayed separately elsewhere on the app (in the main
body area, for example).

What I did was to create my authentication view as a partial,
“_authenticate.rb” instead of “authenticate.rb” and then rather than
rednering it directly, I included a :render in the sidebar part of my
application.rhtml file to display the “_authenticate.rb” partial.

The next refinement was achieved when I introduced other controllers, so
that the same partial is accessed whichever controller’s views were
being rendered. To this end, I created a new directory “views/shared”
and moved the partial in there. I then changed the render instructio to
this:

render :partial => 'shared/authenticate'

This works nicely for me. I hope I am doing it the right way!

I think the AWDWR book is deficient in this respect as it does not
really explain how to do this: I did what I did through trial and error;
what I did works but I hope I am doing it an “accepted way”.

I would be interested to here others’ thoughts on this method.

Thanks,
John

John - Thank you for taking the time on this - I really appreciate it,
and I think others will as well.

I am slightly behind you on the rails learning curve, but I had
suspected that your approach might be the right path.

One question for you though about “automatic rendering” from a
controller. When you call render for a partial in a controller’s
action, does the controller still automatically call its own render?

I have several models in my app, with one representing independent
objects (rows), with several other dependent objects (rows) through a
one to many relationship.

What I really want to happen is to have the controller’s action render
the information for the object it is responsible for, then each of the
dependent objects in turn. My understanding of the “automatic” render
call process is that a call to render the view for the action is done
automatically on exit. So instead of getting the information I’m
looking for at the top, I’ll get it at the bottom of the page after
all of the dependent objects have had the render partial calls done.
Do I have this wrong?

On Oct 12, 5:51 am, John L. [email protected]

I found myself in a similar position after reading AWDWR and other
tutes. Left with a “now what” feeling re: page assembly processes.
Controller → view-> layout. 3 files. Done. Well, pretty much not
done for any site I’ve ever designed.

Also for me, the way Rails starts with the view file and then gets
the layout to wrap around the view is backwards from what I am used
to. So, before I could go further, I had to focus on solving the
modular page assembly part. Still not done sorting out the various
ways to throw data down the pipe through partials, but that’s what
I’ll focus on tomorrow.

Meanwhile, I wrote an article on what I’ve figured out so far in
using layouts to spawn the inclusion of multiple panels to construct
the page. I’ll be reworking/extending it as I go to fill in this gap
for deeper examples of real-world complex pages.

If anyone wants to offer comments/corrections/questions to address,
I’d appreciate the input. Who knows, I might be totally embarrassing
myself :slight_smile:

http://gregwillits.wordpress.com/2007/10/16/modular-page-layouts-in-
ruby-on-rails/

– gw

Hi JSJ - yes no problem, glad to help and it’s good to find out if I
have it right myself :wink:

When you call render for a partial in a controller’s
action, does the controller still automatically call its own render?

When you have a layout (mine is in application.rb), each section (i.e.
“div”
for header, body, sidebar, footer, etc, can contain render instructions
for
the content to go in that specific area.

For example, my sidebar has

render :partial => ‘shared/authenticate’

and

self << content_for_sidebar rescue nil

The first of these renders my authentication partial, and the second
allows
me to specify (optionally, hence the “rescue nil”) content to display in
the sidebar below it.

The authentication partial is common to any controller using this
layout. The content_for_sidebar is specific to the controller’s action
that is being displayed.

Remember the event that causes a page to be displayed in a browser is
the submission of a specific URL requesting a specific controller
action:

http://www.mysite.com/my_controller/my_action

will cause the action my_action within my_controller to be executed. If
my_controller contains a “layout” statement then that specific layout
will
be used, or if “application.rb” exists then that will be used.

The layout can render as many things as it likes, but they will either
be
shared or relative to my_controller’s my_action. The latter are defined
in the view file for my_controller/my_action.rhtml.

The view file normally contains a default view which is rendered using

self << content_for_layout

However you can also add additional views to the named file by doing
this:

<% content_for(:sidebar) do %>

render this in the sidebar with "self << content_for_sidebar"

<% end %>

I place these specific blocks at the end of the view file, after all of
the code for the “default” view.

These are all the techniques I use and, hopefully, I’m using them right!

a call to render the view for the action is done
automatically on exit. So instead of getting the information I’m
looking for at the top, I’ll get it at the bottom of the page

I think that, by using render or content_for in your layout where YOU
want the layout to appear means you can get your page design to work
however you want.

What I really want to happen is to have the controller’s action render
the information for the object it is responsible for, then each of the
dependent objects in turn. My understanding of the “automatic” render

I haven’t extensively played with views that have multiple models yet,
but
it is possible and I believe the “depot” example in AWDWR does this when
displaying the cart. I am pretty sure you’ll be able to do what you
want.

Hope this is useful.
John.

Hi Greg,

I read your article and it seems we’re on the same page about how this
should be done, which is great considering AWDWR (or anything else I’ve
found) comes nowhere even close to describing this most fundamental
foundation for designing a REAL rails app.

One question for you, I wondered why you specify a “layout” in your
controller code rather than relying on the application’s default
“/views/layouts/application.rhtml” file to define the application-wide
layout?

John

On Oct 16, 2007, at 12:56 PM, John L. wrote:

I read your article and it seems we’re on the same page about how this
should be done, which is great considering AWDWR (or anything else
I’ve
found) comes nowhere even close to describing this most fundamental
foundation for designing a REAL rails app.

One question for you, I wondered why you specify a “layout” in your
controller code rather than relying on the application’s default
“/views/layouts/application.rhtml” file to define the application-wide
layout?

I will typically have several layouts in any one application. Most
pages might follow a core 3column or 2column layout, where a few will
need more elbow room and drop a column. Different sections of a site
will have different needs for standard panels, etc.

While all of these details can be handled dynamically while using one
layout (which does little more that structure the head and body), I
find it less prone to CSS wrestling matches and generally clearer to
have multiple layouts which provide a clean and clear structure and
purpose for a given page style. Some might consider it redundant, but
I find the advantages outweight it.

Also, one things Rails seems to lack is the concept of web site
modularity. If it’s there’s I don’t see it yet. In my own framework,
if I create a news reading/writing section to a web site, that
section lives under one folder. I can literally drag and drop that
one folder from project to project and everything I need is
encpsulated (without generating redundant code from module to
module). Update the CSS, and it’s ready use. So, my history with that
type of development also tends to lean on separate layouts because as
stand-alone shells, they’re easier to share project to project.

Having said that, I’m used to a view building environment that seems
to be very different from Rails, so while I’m trying to grok the
Rails way, I may still be projecting a little bit of “my way” onto
it. We’ll see where I end up in a few weeks. Hopefully, I can
transfer my acquired experience and the comments of others into a
useful reference in that article.

– gw

Greg,

a good write up and an interesting discussion.

A nicely presented pdf, just, a few editorials you may like to be
aware of on Page 8, using content_for:

The second code fragment has left for right.
the penultimate para starting OK - wording of first two sentences
needs tidying.
second column, first text para - about_right should be aboutus_right

The topic was particularly useful reading for me at the moment. I am
already doing something similar to provide a prompt/errors div/partial
that appears at the bottom of the screen. I use a partial for my own
error messages, based on the rails methods and also put flash content
into the div. I have yet to find the best way to convey the
error_messages_for information to the partial. At the moment, I set
an instance variable in the view which is picked up by the partial in
the layout.

Also, one things Rails seems to lack is the concept of web site
modularity. If it’s there’s I don’t see it yet. In my own framework,
if I create a news reading/writing section to a web site, that
section lives under one folder. I can literally drag and drop that
one folder from project to project and everything I need is
encpsulated (without generating redundant code from module to
module). Update the CSS, and it’s ready use. So, my history with that
type of development also tends to lean on separate layouts because as
stand-alone shells, they’re easier to share project to project.

I really like that idea, but I am not quite clear about what you mean
by a section living under a folder. eg What lives in the folder, and
how does it get accessed? I also like your point about separate
layouts. Having an app that has now grown, I can see the sense in
splitting this even with very similar layouts, just to make the css
more manageable - thanks, I find examples of how others structure
things really useful.

At the moment, I have just started experimenting with redBox modal
popup boxes eg. to provide lookups for complex forms. This has given
me a nice product, but a bit of a headache managing partials and
controllers. I wanted to abstract out some parts of the handling such
as look ups using auto_completer, edit and new. For example, trying
to have common partials for customer where they can be used in
different contexts, eg orders, repairs etc. Although I have got it
working, I feel like I have begun to introduce spaghetti partials.
with one linking to another etc. This also causes a headache of which
controller things go in and calling partials from different
controllers also gives problems if the right parts of the view are not
correctly rewritten, the submit/link to remote can end up making the
request to the wrong controller. I dont have any wisdom in this area,
I am still thinking it through.

Tonypm

On Oct 23, 2007, at 1:07 AM, tonypm wrote:

Greg,
a good write up and an interesting discussion.

A nicely presented pdf, just, a few editorials you may like to be
aware of on Page 8, using content_for:

The second code fragment has left for right.
the penultimate para starting OK - wording of first two sentences
needs tidying.
second column, first text para - about_right should be aboutus_right

Thanks.

The topic was particularly useful reading for me at the moment. I am
already doing something similar to provide a prompt/errors div/partial
that appears at the bottom of the screen. I use a partial for my own
error messages, based on the rails methods and also put flash content
into the div. I have yet to find the best way to convey the
error_messages_for information to the partial. At the moment, I set
an instance variable in the view which is picked up by the partial in
the layout.

I haven’t fully reviewed Rails error handling systems yet. I’ve
always had a global error manager for that stuff so it was available
to everything at any time. Error handling was always a framework-wide
service in my apps. It seemed to me to be one of those things that
was worth allowing all objects of the app to know about.

I really like that idea, but I am not quite clear about what you mean
by a section living under a folder. eg What lives in the folder, and
how does it get accessed?

You can probably get a better idea of what I mean from this page:
http://www.pageblocks.org/ftrs/api_site

I also like your point about separate
layouts. Having an app that has now grown, I can see the sense in
splitting this even with very similar layouts, just to make the css
more manageable - thanks, I find examples of how others structure
things really useful.

Yeah at some point, one layout with a boatload of conditional and
modal clag hanging about just doesn’t make sense to me. Takes longer
to find what need to be changed than it does to maintain a few very
simple duplicates. DRY is only useful if it saves you time & hassle.

controllers also gives problems if the right parts of the view are not
correctly rewritten, the submit/link to remote can end up making the
request to the wrong controller. I dont have any wisdom in this area,
I am still thinking it through.

At some point you have to think about the difference between when
partials can be reused because they happen to be similar vs when
they should be reused because you really do want where they’re
applied to stay identical. I’ve seen cases where people pull out code
to be shared because it happened to be the same at that point, but it
wasn’t stuff that particularly needed to stay the same and indeed was
subject to evolving design whim. Something to think about if applicable.

If you end up with partials that have conditional code in them to do
X vs Y based on how they got called, or who they got called by, all
that kind of code belongs back up in the controller (sometimes in a
helper). It’s possible you have a case where there is a lot of view
logic. Post controller, but pre view logic that will feel out of
place in either Rails box. In that case you generate another layer of
logic beteeen the two so both controllers and views can stay clean.
This can happen when you’re developing apps that deliver to standard
browser and mobile browsers. If your controllers are particularly
complex with data management, it can be nice to not have to bulk them
up with a lot of decision making about the display. So you push that
off to another layer. Most web apps really don’t need that, but some
would. If anything, just think about whether you’re ending up with
code in partials that belong in controllers. You may need to create
small methods in the application.rb file that handle those decisions
and any re-mapping of data structures or object names to allow the
partials to be usable by multiple controllers. And of course, if yo
find yourself reusing partials, sometimes you go back and refactor
your data structures because you’ve now learned they really are the
same or similar things, so you can rename them to reflect that (and
make them easier to pass to partials).

Anyway, just shootin’ from the hip here…

– gw

I do something similar it sounds in my application using embedded
scaffolds.
Take a look at activescaffold. Then you can next and have multiple
tables
on one page. You can also mix and match your find clauses as well.

Pretty flexable.