Views in one controller reaching out to other controllers (b

Hello all. For the purpose of my question, let’s imagine we’re building
some
search functionality.

You’re a sales person (you poor sap). And you’re hanging out in the
SalesCenterController. You need to do a search for available
productions;
you’ve decided to be cool and use Ajax. Do you…

a) Make a remote call to an action in your current controller (e.g.
SalesCenterController#search_productions)
b) Make a remote call to a separate controller for the necessary search
functionality (e.g. ProductionsController#search)

Thoughts?

  • Rabbit

Factor out the common search code into a method, put it in
application.rb, and call it from each controller that needs it.

        - dan


Dan K. mailto:[email protected]
http://www.dankohn.com/ tel:+1-415-233-1000

Dan K. wrote:

Factor out the common search code into a method, put it in
application.rb, and call it from each controller that needs it.

        - dan


Dan K. mailto:[email protected]
http://www.dankohn.com/ tel:+1-415-233-1000

Dan,

Do you by chance have an example of this that works with pagination?
When I do a custom search I get a pagination error when I try to page to
the next set of items.

Rabbit (Daniel),

You working on a CRM app? If so, would love to touch bases with you and
determine if we can trade any functionality. I have a crm app tailored
a little to a specific industry but am sure there are common elements.

Thanks,

Michael

Hmm… that’s a possibility. However, the searching itself is trivial…

@people = Person.fulltext_search(params[:query])

There’s not a whole lot to factor out.

Maybe my example is too specific. I think it would help if I could get a
sense of what other people are doing (or would do) in a given situation.
Take these for example…

  1. Would you let a view rendered by controller A reach out to controller
    B?
  2. Regarding partials, say you have at least two places in your
    application
    where you can search for customers. If the views presented are identical
    in
    each place, where should that view be stored?
  3. Imagine you have a controller called People. In controller B you
    determine you need to do a search for people. Would you add a method to
    controller B or call out to the search method in the people controller?

Obviously there’s more than one way to do it; and I’m stumbling over all
those choices. Help! :slight_smile:

  • Rabbit

I think your issue here may be that you’re assuming that controllers
should only work with one model. There’s no such expectation.

  1. Would you let a view rendered by controller A reach out to
    controller B?

Definitely not. Views call to one and only one controller.

  1. Regarding partials, say you have at least two places in your
    application where you can search for customers. If the views
    presented are identical in each place, where should that view be
    stored?

Put the partial in views/shared.

  1. Imagine you have a controller called People. In controller B you
    determine you need to do a search for people. Would you add a
    method to controller B or call out to the search method in the
    people controller?

Feel free to do as many searches of as many different models as you
want in a controller. Whatever you need to populate the view. But
having a controller call another one is just confusing things for no
reason. Factor out the common search code into a method, put it in
application.rb, and call it from each controller that needs it.

        - dan

Rabbit,

My answers to your questions (which may be different than what others
say so let’s see):

  1. Yes. I would let it “reach out”.
  2. In my opinion, the view shoud be stored with the proper controller
    from which the view is coming. I do this a lot with children records.
    For example, I have a list of activities that can show up under orders,
    leads or activities in itself. In my activity controller, I have a
    “list” view which calls a partial "_activity_list.rhtml. From all other
    controllers that show a list of activities, I call the
    “_activity_list.rhtml” partial. This allows the view to maintain a
    consistent look and feel across the entire application and reduce
    duplication. It also allows the view to be in the proper
    “organizational” structure of where I think it should be. As an
    example, from my lead controller, I do something like this:

<%= render( :partial => “activity/activity_list” ) %>

  1. I would call out the search method in People, unless you have it in
    the application specific form like Dan pointed out. I suspect you would
    then have to pass in the model/action anyway so that it knew which model
    to query.

Let’s hope I’m doing it right! :slight_smile: It certainly works for our
application.

Regards,

Michael

Community,

As you can see, Dan’s response went completely against mine! Am I doing
things completely wrong?

I can undestand point number one - a view belonging to one and only one
controller. I may have misused this to some degree. An example where I
have “reached out” to another controller is when I’m on a lead and I
want to convert it to an order. I call the order controller where I
guess I could call the lead controller and have a new order created from
it.

However, most concerning to me is item two regarding views that may be
reused in many different places but that pertain to a specific
controller.

For example, I would expect things like header/footer/nav menu’s/etc…
to go into shared. But if I have a partial that is specific to a
particular controller and model then I think that partial should go into
the views for relating to the controller/model to which it belongs, even
though it is used by many different “shared” views. In my example, I
have a list of activities that show up in many different places of the
application. Am I wrong to have that partial under the activities
views? Should it be moved to shared?

Please advise! I’m definitely looking for “best practices” and also to
understand a little of the logic if I am incorrect in my use of
partials.

Thanks,

Michael

I could certainly be wrong as well.

I can undestand point number one - a view belonging to one and only
one
controller. I may have misused this to some degree. An example
where I
have “reached out” to another controller is when I’m on a lead and I
want to convert it to an order. I call the order controller where I
guess I could call the lead controller and have a new order created
from
it.

I guess it depends on what you mean by “reached out”. Think of
scaffolding, where the edit.rhtml (which is populated by
edit_controller.rb) submits its form to update. Update then decides
whether to send the user back to edit or show. This allows you to
reach across controllers. So, it’s completely reasonable for a page
to be generated with the edit controller, have it’s submission
processed by the update controller, and then be sent to the show
controller. But one controller is always in charge.

views? Should it be moved to shared?
I put partials under the view of the relevant controller if only (or
mainly) methods of that controller use it. But if a partial is
shared by multiple controllers (which is what I assume the original
poster meant when he said “two places in your application”, then
views/shared seems like a good choice. To quote AWDWR v2beta5, page
496: “[T]o share partials across controllers… [t]he convention
among Rails applications is to store these shared partials in a
subdirectory of app/views called shared”

        - dan


Dan K. mailto:[email protected]
http://www.dankohn.com/ tel:+1-415-233-1000

“I think your issue here may be that you’re assuming that controllers
should
only work with one model. There’s no such expectation. … Whatever you
need to populate the view.”

You’re dead on. DHH’s keynote about a controller’s goal in life is to be
simplified to the point where all it’s doing is CRUD rests heavy on my
shoulders.

I understand the idea and drive behind modeling relationships in
addition to
objects, but sometimes it just doesn’t seem possible. (Possible, that
is, to
reduce everything in a controller to CRUD – example: where does a
search
function belong?)

Anyway, thanks much for the guidance, Dan. I appreciate it. :slight_smile:

  • Rabbit