1

I'm working on a CRUD interface for managing users in my application. I have a constant User::ROLES that is an array with the names of valid user roles in my app (admin, teacher, student).

What I'm wanting to do is, in the index action of the controller, have a block that iterates through the ROLES constant and creates a scoped instance variable from @users (which is already initialized before the block). Here's what the index method looks like so far:

def index
    @users = user.all
    #@students = @users.where(:role => "student") # This works by itself
    User::ROLES.each do |r|
        @r = @users.where(:role => r.to_s)
    end
end

So I want to be able to name the instance variable by what's passed through the block, so @r creates @admin, @teacher, etc. Since I'm new to ruby and rails, I don't quite understand the syntax for doing this. Who knows? There's probably a better way to do it anyways.

EDIT

Just to let everyone know, I'm hoping to use this in the view on the index action to display a list of users grouped by their role. Of course, it will be used in other ways too throughout the CRUD interface, which is why I didn't clarify the use-case earlier, since it's multi-purpose.

1 Answer 1

6

This is probably a bad idea. If you change a role in your model, you will need to update your view accordingly to use a different instance method. A better way to handle this would be to simply group users by their role:

@users = User.group(:role).all

Which would give you a hash with keys named after each role that you could easily use to build a dynamic view:

<% @users.each_pair do |role, users| %>
  <h2><%= role.to_s.titlelize %></h2>
  <% users.each do |user| %>
    ...
  <% end %>
<% end %>

You can also access users with a specific role if needed:

<h2>Admin users:</h2>
<%= @users[:admin].map(&:name).to_sentence %>
Sign up to request clarification or add additional context in comments.

8 Comments

"If you change a role in your model, you will need to update your view accordingly to use a different instance method". Now you're contradicting yourself. If you are accessing specific roles via @users[:admin], you have to adapt your views exactly the same way if you change a role name.
Thank you. I didn't know about the group method and each_pair. That helps a lot.
Well, I'm not sure why, but the group method wasn't working. It returned the user records like normal without grouping. I ended up doing @users = User.all.group_by(&:role) which then works as expected.
You're on Rails 3, right? The difference is that Model.group.all uses ActiveRecord to alter the SQL query issued, where Model.all.group_by is selecting the records and then grouping them in Ruby. That's not nearly as warm and fuzzy.
@coreyward Without a reference that is just your opinion. I believe there is no generally agreed upon design guideline for dynamic languages. Also I was just adressing your sentence "If you change a role in your model, you will need to update your view accordingly to use a different instance method", which is not an argument at all for the reason I mentioned (two years ago!)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.