1
\$\begingroup\$

My User model has multiple roles (utilizing CanCan). Each role's dashboard view is different enough to warrant a partial for each role (admins get big-picture reports of users and app activity, students get big-picture overviews of grades, current courses, and lessons to be taken).

At first I had a case statement to iterate through the views based on current_user.role (of course, that was just temporary, even I know that!). Now, I have this:

<%= render "#{current_user.role}" %>

This doesn't feel right. What's the proper way to dynamically render partials (or maybe this method is perfectly fine)? Also, please mention why the proper way is best, as I want to learn from this.

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

You can override ActiveModel#to_partial_path if you want - same as how you might override to_param. See the documentation (and be sure to check the source too - they're doing some caching that's elided in the docs, but might be worth looking in to).

Anyway, in your case, you could likely just redefine the method on the User model like so:

# in app/models/user.rb
class User < ActiveRecord::Base
  # ...
  def to_partial_path
    collection = ActiveSupport::Inflector.tableize(self)
    "#{collection}/#{self.role}"
  end
end

This way, you can use render as you would normally. You'll only be doing what Rails is already doing - just a little differently.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks Flambino. I'm wondering though, what benefits would this have over the method I'm using currently? It's a bit more verbose and, to me at least, the other method seems more readable. Also, I'm guessing from the code that I'd call this with something like render user and to_partial_path would select the correct partial, right? \$\endgroup\$ Nov 14, 2012 at 21:59
  • \$\begingroup\$ @GorrillaMcD it's (negligibly) more verbose, but arguably more correct, since it's "the Rails Way" to have a model define its partial path. Besides, role is defined on the model, so why shouldn't the partial path be when it's dependent on the role? But really, there aren't many alternatives: The partial path is an expression; it's either inline in the view, or in a method. Your code uses the former, this uses the latter (which can be anywhere, but this is in keeping with conventions). Not much else you can do. \$\endgroup\$
    – Flambino
    Nov 14, 2012 at 22:19
  • \$\begingroup\$ Thanks for the explanation. I was just curious as to why it's better that's all. Thanks again. \$\endgroup\$ Nov 14, 2012 at 22:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.