On 20 Aug 2011, at 13:35, Stan McFarland wrote:
experience comes back to haunt me.
There is no one ‘correct’ way to do this. Both of your suggestions will
work. But I’d agree with your instinct that they both feel a little bit
hackish.
One solution would be to specify a different controller to handle users
scoped inside groups:
resources :groups do
resources :users, :controller => ‘group_users’
end
Then the concept of creating a user inside a group, and the concept of
creating a user, can be handled in completely separate controllers.
The problem with this is that you’ll be passing parameters like :user =>
{:name => “Bob S.”, :email => “[email protected]”, } to your
UsersController, while passing parameters like :user_id => 2 to your
GroupUsersController. It feels like theres some inconsistency there.
So you could invent a new concept, called a ‘membership’:
resources :groups do
resources :memberships
end
When a user joins a group, you’re not really creating a user – you’re
creating a membership. When a user leaves a group, you’re not really
deleting a user – you’re deleting a membership.
Note that a resource doesn’t have to match one-to-one with a
database-backed model. So you can expose this concept of a membership at
your controller level, and let the controllers deal with converting that
to model talk:
POST ‘/groups/1/memberships’, {:membership => {:user_id => 2}}
class MembershipsController < ActionController::Base
def create
@group = Group.find(params[:group_id])
@user = User.find(params[:membership][:user_id])
@group.users << @user
redirect_to wherever
end
end
Like I say, there isn’t a ‘correct’ way of handling this kind of thing,
but I personally like the idea of exposing the semantics of your
application like this, and trying to think of things in terms of CRUD
where possible.
Chris