I am still learning Rails and the relationships are still a little confusion. So I apologize in advance for the repetition of this question. I am building a user rating system for words and quotes. If I wanted a user to be able to rate a word or quote only once, how can I set up the ratings table so it will have the appropriate relationships. Since the rating model is a bit polymorphic (rate words or quotes), I am not sure if I need a "bridge table". I want to be able to do things like word.rating.value quote.rating.value user.rating.value Any direction is greatly appreciated, and if you can throw in some comments behind the code, even better. Also, would you suggest putting the only one rating per user constraint in the db or as a validate_unique.. Thanks, Jason --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
To quickly answer your second question, you need both. The reason for that is that validates_uniqueness_of does not guarantee fully unique column values, since it''s at the application level. The unique constraint in the db schema can be viewed as a backup. I''ll answer your main question shortly. On Apr 13, 2:10 pm, Jason <mccreary.ja...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I am still learning Rails and the relationships are still a little > confusion. So I apologize in advance for the repetition of this > question. > > I am building a user rating system for words and quotes. If I wanted a > user to be able to rate a word or quote only once, how can I set up > the ratings table so it will have the appropriate relationships. Since > the rating model is a bit polymorphic (rate words or quotes), I am not > sure if I need a "bridge table". I want to be able to do things like > > word.rating.value > quote.rating.value > user.rating.value > > Any direction is greatly appreciated, and if you can throw in some > comments behind the code, even better. Also, would you suggest putting > the only one rating per user constraint in the db or as a > validate_unique.. > > Thanks, > Jason--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks for the initial response. I look forward to the main answer. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Srdjan Pejic wrote: [...]> The unique > constraint in the db schema can be viewed as a backup. > > I''ll answer your main question shortly.A philosophical quibble: in my opinion, it is the unique constraint in the DB that should be considered primary. The validation in the application layer is only there to prevent the DB from throwing duplicate key errors. Application-level validation cannot replace a properly constructed database schema. I''ll get off my soapbox now...I just want to make it clear that the database layer is the *only* place where it is possible to have airtight integrity checking. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I appreciate the debate, and I agree the constraint should be the DB as a primary. Back to my main question though - how should the relationships be set up for a rating system? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hmm, let''s see... Jason wrote: [...]> I am building a user rating system for words and quotes. If I wanted a > user to be able to rate a word or quote only once, how can I set up > the ratings table so it will have the appropriate relationships. Since > the rating model is a bit polymorphic (rate words or quotes), I am not > sure if I need a "bridge table".A bridge table has to do with many-to-many relationships, not polymorphic relationships, unless I''m misunderstanding.> I want to be able to do things like > > word.rating.value > quote.rating.value > user.rating.valueHow about using STI? class Word < Rateable has_many :ratings end class Quote < Rateable and class User < Rateable likewise class Rating < ActiveRecord::Base belongs_to :rateable, :polymorphic => true end (Syntax may be slightly off...working from memory.) There might be a plugin to make this easier. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I don''t know if STI is appropriate here. You should probably have a model called Rating which is the many side of one-to-many with the User model. The Rating model should be polymorphic so that you can use it to rate both Word and Quote objects. So, it would most likely look like this: class User :has_many => :ratings end class Rating :belongs_to => :user :belongs_to => :rated, :polymorphic => true end class Word :has_one :rating, :as => :rated end class Quote :has_one :rating, :as => :rated end The ratings table needs to have rated_id (integer) and rated_owner (string) as columns in order to support the polymorphic behaviour. What this will give you is a collection of ratings for a user (the logic of adding this is something you need to figure out), and each Rating instance will have a property called *rated*. That will reach in and grab either the Quote or the Word being rated. The score, or however you''re rating them, needs to be in the Rating model. Let me know if you need more clarification. On Apr 16, 1:08 am, Marnen Laibow-Koser <rails-mailing-l...@andreas- s.net> wrote:> Hmm, let''s see... > > Jason wrote: > > [...] > > > I am building a user rating system for words and quotes. If I wanted a > > user to be able to rate a word or quote only once, how can I set up > > the ratings table so it will have the appropriate relationships. Since > > the rating model is a bit polymorphic (rate words or quotes), I am not > > sure if I need a "bridge table". > > A bridge table has to do with many-to-many relationships, not > polymorphic relationships, unless I''m misunderstanding. > > > I want to be able to do things like > > > word.rating.value > > quote.rating.value > > user.rating.value > > How about using STI? > > class Word < Rateable > has_many :ratings > end > > class Quote < Rateable > and > class User < Rateable > likewise > > class Rating < ActiveRecord::Base > belongs_to :rateable, :polymorphic => true > end > > (Syntax may be slightly off...working from memory.) > > There might be a plugin to make this easier. > > Best, > -- > Marnen Laibow-Koserhttp://www.marnen.org > mar...-sbuyVjPbboAdnm+yROfE0A@public.gmane.org > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I don''t know if STI is appropriate here. You should probably have a model called Rating which is the many side of one-to-many with the User model. The Rating model should be polymorphic so that you can use it to rate both Word and Quote objects. So, it would most likely look like this: class User :has_many => :ratings end class Rating :belongs_to => :user :belongs_to => :rated, :polymorphic => true end class Word :has_one :rating, :as => :rated end class Quote :has_one :rating, :as => :rated end The ratings table needs to have rated_id (integer) and rated_owner (string) as columns in order to support the polymorphic behaviour. What this will give you is a collection of ratings for a user (the logic of adding this is something you need to figure out), and each Rating instance will have a property called *rated*. That will reach in and grab either the Quote or the Word being rated. The score, or however you''re rating them, needs to be in the Rating model. Let me know if you need more clarification. On Apr 16, 1:08 am, Marnen Laibow-Koser <rails-mailing-l...@andreas- s.net> wrote:> Hmm, let''s see... > > Jason wrote: > > [...] > > > I am building a user rating system for words and quotes. If I wanted a > > user to be able to rate a word or quote only once, how can I set up > > the ratings table so it will have the appropriate relationships. Since > > the rating model is a bit polymorphic (rate words or quotes), I am not > > sure if I need a "bridge table". > > A bridge table has to do with many-to-many relationships, not > polymorphic relationships, unless I''m misunderstanding. > > > I want to be able to do things like > > > word.rating.value > > quote.rating.value > > user.rating.value > > How about using STI? > > class Word < Rateable > has_many :ratings > end > > class Quote < Rateable > and > class User < Rateable > likewise > > class Rating < ActiveRecord::Base > belongs_to :rateable, :polymorphic => true > end > > (Syntax may be slightly off...working from memory.) > > There might be a plugin to make this easier. > > Best, > -- > Marnen Laibow-Koserhttp://www.marnen.org > mar...-sbuyVjPbboAdnm+yROfE0A@public.gmane.org > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Srdjan Pejic wrote:> I don''t know if STI is appropriate here.On second thought, you''re absolutely right. I don''t know what the heck I was thinking. :)> > You should probably have a model called Rating which is the many side > of one-to-many with the User model. The Rating model should be > polymorphic so that you can use it to rate both Word and Quote > objects.[...] Yeah, this is what I was trying for. I just introduced STI in an inappropriate place. Note, though, that *not* using STI makes foreign-key validation somewhat harder.> > So, it would most likely look like this: > > class User > :has_many => :ratings > end > > class Rating > :belongs_to => :user > :belongs_to => :rated, :polymorphic => true > end > > class Word > :has_one :rating, :as => :rated > end > > class Quote > :has_one :rating, :as => :rated > endThose should be has_many... Best, Marnen -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> Those should be has_many...I''m not sure if I understand you here. You mean that Word and Quote should have more than one rating per instance? That''s why I put them as has_one. On Apr 16, 10:53 am, Marnen Laibow-Koser <rails-mailing-l...@andreas- s.net> wrote:> Srdjan Pejic wrote: > > I don''t know if STI is appropriate here. > > On second thought, you''re absolutely right. I don''t know what the heck > I was thinking. :) > > > > > You should probably have a model called Rating which is the many side > > of one-to-many with the User model. The Rating model should be > > polymorphic so that you can use it to rate both Word and Quote > > objects. > > [...] > > Yeah, this is what I was trying for. I just introduced STI in an > inappropriate place. > > Note, though, that *not* using STI makes foreign-key validation somewhat > harder. > > > > > > > So, it would most likely look like this: > > > class User > > :has_many => :ratings > > end > > > class Rating > > :belongs_to => :user > > :belongs_to => :rated, :polymorphic => true > > end > > > class Word > > :has_one :rating, :as => :rated > > end > > > class Quote > > :has_one :rating, :as => :rated > > end > > Those should be has_many... > > Best, > Marnen > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---