Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - Many Models in One View

I need to access multiple models from a single view. Previously, my links_controller was only used to provide link resources sorted in different ways. Now I would like to include a partial (I'm assumning) which shows the top users sorted by score (@users = User.all.sort_by(&:score))

I'm aware that I could plug this code into every link action and access it from the view but this doesn't seem to be the "ruby way" and I will need to access more models in the near future. This could get really dirty, are there any techniques for this situation?

Notes:

  • I see my application going in the direction of having a single format with dynamic page contents, in essence, a typical web app.
  • I'm aware of before_filter but this seems cumbersome, considering the direction that I would like the application to go in. Eventually accessing several models from any view.
like image 252
Dru Avatar asked Nov 23 '11 15:11

Dru


2 Answers

This sort of thing is best encapsulated as a helper method that's exercised by that particular partial. For instance if this was your partial _user_listing.html.erb:

<% users_by_score.each do |user| %>
   ...
<% end %>

Then you'd implement the users_by_score method in a helper file included by all the relevant controllers, or ApplicationHelper if it's that prevalent:

def users_by_score
  User.all.sort_by(&:score)
end

In other MVC systems this would be considered a sub-view with its own controller, but in Rails the best you can do is to have helper methods.

like image 130
tadman Avatar answered Oct 16 '22 23:10

tadman


There are several options to handle this.

I believe that controllers are the glue between the view and models, and that controllers should do all data-retrieving. The helpers are only to help your view-code become more readable.

So, in that light, there are a few options.

Classic Rails approach

We have a large app, where there are a few shared blocks, not related to the current page, but to the current user, where he can see his items, actions, and quickly jump around. This stuff all comes from the database.

We retrieve the data using before_filter methods. Those methods are defined in the ApplicationController. We keep our ApplicationController small by mixing that code (shared behaviour) in.

In our application layout we render the different partials for the data collected in those before filters. Most of those blocks are fixed and always visible.

Cells

I have not used it myself, but a very clean solution, is to use cells. Cells are actually a kind of blocks, with their own controller and views, that you can place on your page. This sounds very interesting, and definitely interesting if you have a portal-kind of site with portlets (does anybody know what I mean with that? I feel so old now ;)).

Switch to client MVC

If you are switching to a single-page webapplication, like Gmail, it could also be a good time to switch to using a javascript MVC framework. Your page could then be made up using different areas, each with their own model and view (template), which link to your rails controller.

There are a ton of libraries at the moment, everybody seems to be using backbone these days, but if you take this route, I would recommend to check out spine.js: it has an awesome rails integration and dead easy to get started with.

Hope this helps.

like image 41
nathanvda Avatar answered Oct 17 '22 00:10

nathanvda