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?
Daniel Drehmer wrote:> 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. -- Posted via http://www.ruby-forum.com/.
2009/9/3 Daniel Drehmer <danieldrehmer-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> > 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?If you haven''t seen them already have a look at the Rails Guides. Particularly Getting Started and ActiveRecord Associations. Colin
> Any idea of how to approach this?Sounds like Users, Sandboxes, and Participations - the main point being a full join table (participation) with additional attributes User has_many :participations has_many :sandboxes, :through => :participations Sandbox has_many :participations has_many :users, :through => :participations Participation user_id sandbox_id role (which is user, or admin, or donkey, or whatever) belongs_to :user belongs_to :sandbox Or something along those lines... -- Posted via http://www.ruby-forum.com/.
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. This was the missing piece. Thank you! On 3 set, 13:21, Ar Chron <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Any idea of how to approach this? > > Sounds like Users, Sandboxes, and Participations - the main point being > a full join table (participation) with additional attributes > > User > has_many :participations > has_many :sandboxes, :through => :participations > > Sandbox > has_many :participations > has_many :users, :through => :participations > > Participation > user_id > sandbox_id > role (which is user, or admin, or donkey, or whatever) > belongs_to :user > belongs_to :sandbox > > Or something along those lines... > -- > Posted viahttp://www.ruby-forum.com/.
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? On 3 set, 16:29, Daniel Drehmer <danieldreh...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> 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. > > This was the missing piece. Thank you! > > On 3 set, 13:21, Ar Chron <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: > > > > > > Any idea of how to approach this? > > > Sounds like Users, Sandboxes, and Participations - the main point being > > a full join table (participation) with additional attributes > > > User > > has_many :participations > > has_many :sandboxes, :through => :participations > > > Sandbox > > has_many :participations > > has_many :users, :through => :participations > > > Participation > > user_id > > sandbox_id > > role (which is user, or admin, or donkey, or whatever) > > belongs_to :user > > belongs_to :sandbox > > > Or something along those lines... > > -- > > Posted viahttp://www.ruby-forum.com/.
2009/9/3 Daniel Drehmer <danieldrehmer-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> > 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 Colin> > > > On 3 set, 16:29, Daniel Drehmer <danieldreh...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> 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. >> >> This was the missing piece. Thank you! >> >> On 3 set, 13:21, Ar Chron <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: >> >> >> >> > > Any idea of how to approach this? >> >> > Sounds like Users, Sandboxes, and Participations - the main point being >> > a full join table (participation) with additional attributes >> >> > User >> > has_many :participations >> > has_many :sandboxes, :through => :participations >> >> > Sandbox >> > has_many :participations >> > has_many :users, :through => :participations >> >> > Participation >> > user_id >> > sandbox_id >> > role (which is user, or admin, or donkey, or whatever) >> > belongs_to :user >> > belongs_to :sandbox >> >> > Or something along those lines... >> > -- >> > Posted viahttp://www.ruby-forum.com/. > > >
Also very elucidative, Colin. Thank you very much! On 3 set, 16:58, Colin Law <clan...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> 2009/9/3 Daniel Drehmer <danieldreh...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>: > > > > > 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 > > Colin > > > > > > > On 3 set, 16:29, Daniel Drehmer <danieldreh...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > >> 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. > > >> This was the missing piece. Thank you! > > >> On 3 set, 13:21, Ar Chron <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: > > >> > > Any idea of how to approach this? > > >> > Sounds like Users, Sandboxes, and Participations - the main point being > >> > a full join table (participation) with additional attributes > > >> > User > >> > has_many :participations > >> > has_many :sandboxes, :through => :participations > > >> > Sandbox > >> > has_many :participations > >> > has_many :users, :through => :participations > > >> > Participation > >> > user_id > >> > sandbox_id > >> > role (which is user, or admin, or donkey, or whatever) > >> > belongs_to :user > >> > belongs_to :sandbox > > >> > Or something along those lines... > >> > -- > >> > Posted viahttp://www.ruby-forum.com/.
2009/9/3 Daniel Drehmer <danieldrehmer-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> > Also very elucidative, Colin. Thank you very much! >I am not sure I have ever been accused of being that before. Colin
> @sandbox.users.find_by_role(''donkey'')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''m sure there''s a better way (I haven''t fiddled with named_scope before this evening) but: class Participation < ActiveRecord::Base belongs_to :user belongs_to :sandbox named_scope :who_are_admins, :conditions => [''role = ?'', ''admin''] named_scope :who_are_users, :conditions => [''role = ?'', ''user''] named_scope :who_are_donkeys, :conditions => [''role = ?'', ''donkey''] 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> -- Posted via http://www.ruby-forum.com/.
2009/9/4 Ar Chron <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>:> > I''m sure there''s a better way (I haven''t fiddled with named_scope before > this evening) but: > > class Participation < ActiveRecord::Base > belongs_to :user > belongs_to :sandbox > named_scope :who_are_admins, :conditions => [''role = ?'', ''admin''] > named_scope :who_are_users, :conditions => [''role = ?'', ''user''] > named_scope :who_are_donkeys, :conditions => [''role = ?'', ''donkey'']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>Colin
2009/9/4 Daniel Drehmer <danieldrehmer-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> >> @sandbox.users.find_by_role(''donkey'') > > 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?> > > >
Well the quirky part is that yes, the user has a role, but only in the context of a sandbox. The admin for this one, a user in that one, hopefully a donkey in none... The show does work, but I admit I don''t particularly like the syntax. admins, users or donkeys are participations, not users directly. -- Posted via http://www.ruby-forum.com/.
2009/9/4 Ar Chron <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>:> > Well the quirky part is that yes, the user has a role, but only in the > context of a sandbox. > > The admin for this one, a user in that one, hopefully a donkey in > none... > > The show does work, but I admit I don''t particularly like the syntax. > admins, users or donkeys are participations, not users directly. >If there are (and will always be) only the two categories of participation, ie sandbox owner and regular participant then this might be better Sandbox belongs_to :owner, :class_name => ''User'', :foreign_key => owner_id has_and_belongs_to_many :users User has_many :owned_sandboxes, :class_name => ''Sandbox'', :foreign_key => owner_id has_and_belongs_to_many :sandboxes 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 Colin