I'm a newbie in the programming world and I need some advice regarding
the best way of achieving the task I'm gonna describe.
I've got an User model and another model called Sandbox.
Now I want to make each sandbox have an "owner" (administrator), who
is also an user. The user will be able to own several sandboxes.
Than I want sandboxes to also have "participants" (who are Users, from
the User model/table, but without admin status). A Sandbox should be
able to have many participants and a User should be able to
participate in many sandboxes.
I'm a newbie in the programming world and I need some advice regarding
the best way of achieving the task I'm gonna describe.
I've got an User model and another model called Sandbox.
Now I want to make each sandbox have an "owner" (administrator), who
is also an user. The user will be able to own several sandboxes.
Than I want sandboxes to also have "participants" (who are Users, from
the User model/table, but without admin status). A Sandbox should be
able to have many participants and a User should be able to
participate in many sandboxes.
Any idea of how to approach this?
Do a little research on "belongs_to", "has_many",
"has_and_belongs_to_many" (also known as HABTM), as well as primary /
foreign keys in databases.
It should give you, hopefully, the insight to go on.
Thank you Ar Chron! This is exactly what I was looking for.
I appreciate the other answers, but those reading this thread should
notice that the case I described could not be solved without this
"role" attribute in the participation model.
The only thing that remains unknown to me is how query the list of
users of a given sandbox that have the role "donkey". Is it possible
to use the find method the rails way, without "injecting" sql?
The only thing that remains unknown to me is how query the list of
users of a given sandbox that have the role "donkey". Is it possible
to use the find method the rails way, without "injecting" sql?
Yes of course, you should very rarely find yourself using sql. If you
have a Sandbox called @sandbox then the users of that sandbox are
@sandbox.users so those that have the role donkey are
@sandbox.users.find_by_role('donkey')
At least I think you can do that, I prefer to use a named scope rather
than find_by.. So you might have a named scope on User called
by_role(role) that returns the Users with the given role. Then you
would use
@sandbox.users.by_role('donkey')
Or if you often wanted to find the donkeys then you might have a named
scope on User called donkies that finds them and then you could say
@sandbox.users.donkies
class Sandbox < ActiveRecord::Base
validates_presence_of :name
has_many :participations
has_many :users, :through => :participations
# just to see what the show syntax would look like
def donkeys
self.participations.who_are_donkeys
end
def admins
self.participations.who_are_admins
end
end
And the show.html.erb
<p>
<b>Name:</b>
<%=h @sandbox.name %>
</p>
<p><b>Users (:through)</b><br/>
<% @sandbox.users.each do |user| %>
<%=h user.first+' '+user.last %><br/>
<% end %>
</p>
<p><b>Admins:</b><br/>
<% @sandbox.participations.who_are_admins.each do |admin| %>
<%=h admin.user.first+' '+admin.user.last %><br/>
<% end %>
</p>
<p><b>Users:</b><br/>
<% @sandbox.participations.who_are_users.each do |user| %>
<%=h user.user.first+' '+user.user.last %><br/>
<% end %>
</p>
<p><b>Donkeys:</b><br/>
<% @sandbox.participations.who_are_donkeys.each do |donkey| %>
<%=h donkey.user.first+' '+donkey.user.last %><br/>
<% end %>
</p>
<p><b>Donkeys (sandbox method form):</b><br/>
<% @sandbox.donkeys.each do |donkey| %>
<%=h donkey.user.first+' '+donkey.user.last %><br/>
<% end %>
</p>
If you want a parameterised named_scope you can use
named_scope :by_role, lambda { |role| { :conditions => ['role = ?', role] }
then you can say participations.by_role( 'donkey' )
Colin
end
class Sandbox < ActiveRecord::Base
validates_presence_of :name
has_many :participations
has_many :users, :through => :participations
# just to see what the show syntax would look like
def donkeys
self.participations.who_are_donkeys
end
def admins
self.participations.who_are_admins
end
end
And the show.html.erb
<p>
<b>Name:</b>
<%=h @sandbox.name %>
</p>
<p><b>Users (:through)</b><br/>
<% @sandbox.users.each do |user| %>
<%=h user.first+' '+user.last %><br/>
<% end %>
</p>
<p><b>Admins:</b><br/>
<% @sandbox.participations.who_are_admins.each do |admin| %>
<%=h admin.user.first+' '+admin.user.last %><br/>
<% end %>
</p>
<p><b>Users:</b><br/>
<% @sandbox.participations.who_are_users.each do |user| %>
<%=h user.user.first+' '+user.user.last %><br/>
<% end %>
</p>
<p><b>Donkeys:</b><br/>
<% @sandbox.participations.who_are_donkeys.each do |donkey| %>
<%=h donkey.user.first+' '+donkey.user.last %><br/>
<% end %>
</p>
<p><b>Donkeys (sandbox method form):</b><br/>
<% @sandbox.donkeys.each do |donkey| %>
<%=h donkey.user.first+' '+donkey.user.last %><br/>
<% end %>
</p>
Well, it turns out you can't do it like that. But I'm looking into
named scopes, to see if it solves my problem.
I realise looking at your associations again that I should have said
@sandbox.participations.find_by_role('donkey')
I was thinking that it was the user that had the role rather than the
pariticipation. Does this not work either?
Or along those lines anyway, I may not have got the syntax quite right
This allows one to say
sandbox.owner the user that is the owner
sandbox.users all the other users
user.owned_sandboxes the ones (if any) that he owns
user.sandboxes all the rest that he participates in