I''m working on application where several tables (users,customers,other...) will have the same name structure (prefix, first, middle, last, suffix). I have thought about factoring out the name to a separate model: *** Migrations *** class CreateNames < ActiveRecord::Migration def self.up create_table :names do |t| t.string :prefix t.string :first t.string :middle t.string :suffix end end end class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.integer :name_id # other columns here end end class CreateCustomers < ActiveRecord::Migration def self.up create_table :customers do |t| t.integer :name_id # other columns here end end *** Models *** class Name < ActiveRecord::Base has_one :user has_one :customer end class User < ActiveRecord::Base belongs_to :name end class Customer < ActiveRecord::Base belongs_to :name end I believe the concept is sound but I am concerned about a couple of things. I know that search capabilities by user/customer/other are coming and name searches are going to be in the mix. Am I putting myself into a bad situation by going this way? Are named scopes going to be my friends? What would be the best/fastest way to query the database with this design? Am I abstracting the DB too much? Thanks Pepe -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
I think I would just stick with putting those columns on each table. Is there a specific problem you''re trying to solve by abstracting them out to a separate table? Unless you''re trying to remediate a specific issue, this seems like a solution in search of a problem.> What would be the best/fastest way to query the database with this design?The fastest way would be to put the name columns on each table. When the names are in a separate table, you have to do a join just to get the full record. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Are customers different than users? Can customers also be users? I''d say you should probably just put the customers and users table into one. You can create a table that links off of users that links them to orders (customers) if the need arises. Or if they are two separate roles can always have a flag that denotes it. The normalization is fine on the name breaking it out to its pieces. The problem arises though when you try to break off users and customers that if they are the same person they likely will need to reinsert all of their previous information when signing up. It just adds messiness to the database and makes it harder to associate their information with the user without somehow getting the original table''s name id back to the new one. And imagine if they have two separate name ids... then they have to go and update their values in both tables. I''d personally suggest you combine all three tables unless there is a clear distinction between customers and users, Tim On Tue, May 18, 2010 at 8:58 AM, pepe <Pepe-gUAqH5+0sKL6V6G2DxALlg@public.gmane.org> wrote:> I''m working on application where several tables > (users,customers,other...) will have the same name structure (prefix, > first, middle, last, suffix). > > I have thought about factoring out the name to a separate model: > > *** Migrations *** > class CreateNames < ActiveRecord::Migration > def self.up > create_table :names do |t| > t.string :prefix > t.string :first > t.string :middle > t.string :suffix > end > end > end > > class CreateUsers < ActiveRecord::Migration > def self.up > create_table :users do |t| > t.integer :name_id > # other columns here > end > end > > class CreateCustomers < ActiveRecord::Migration > def self.up > create_table :customers do |t| > t.integer :name_id > # other columns here > end > end > > > *** Models *** > class Name < ActiveRecord::Base > has_one :user > has_one :customer > end > > class User < ActiveRecord::Base > belongs_to :name > end > > class Customer < ActiveRecord::Base > belongs_to :name > end > > I believe the concept is sound but I am concerned about a couple of > things. I know that search capabilities by user/customer/other are > coming and name searches are going to be in the mix. > > Am I putting myself into a bad situation by going this way? > Are named scopes going to be my friends? > What would be the best/fastest way to query the database with this > design? > Am I abstracting the DB too much? > > Thanks > > Pepe > > -- > 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to > rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org<rubyonrails-talk%2Bunsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org> > . > For more options, visit this group at > http://groups.google.com/group/rubyonrails-talk?hl=en. > >-- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Thanks Tim, On May 18, 9:12 am, Tim Shaffer <t...-PGA7PSC7mq/3MY4plGdlAw@public.gmane.org> wrote:> I think I would just stick with putting those columns on each table. > Is there a specific problem you''re trying to solve by abstracting them > out to a separate table? Unless you''re trying to remediate a specific > issue, this seems like a solution in search of a problem.I am not trying to solve a problem, I am trying to design a database that is as flexible as possible. I am trying to abstract ''entities'' to their own models. In this case the name has the same structure in all cases and I am thinking it should have its own ''domain''. I am doing the same with addresses, although I understand the problem is different because a person can have more than one address but not more than 1 name (except for AKAs) or if the person is Jason Bourne... ;)> > What would be the best/fastest way to query the database with this design? > > The fastest way would be to put the name columns on each table. When > the names are in a separate table, you have to do a join just to get > the full record.I understand that but there are also named scopes, which make your life much easier than coding manual joins. The question specified "with this design" hoping somebody would be kind enough to point me into the right direction if I finally go the route I described. Thanks a lot. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
pepe wrote:> > I have thought about factoring out the name to a separate model: >Most of this decision depends on how you intend to treat your Users and Customers. Perhaps you just have people, with a flag attribute on each, or people with related models of Customer-specific info and User-specific info. Is a User really different from a Person (will you track people who aren''t users or customers - if so, then Person isn''t abstract)? But only you know the answers to these questions. I think of names (first, last, middle, full, nickname, etc) as attributes of some model, not a model of its own... Sounds like you *could* have a base (abstract) class of Person, then do class Person < ActiveRecord::Base self.abstract_class = true # common methods go here end class User < Person # User table has all the fields it needs # User specific methods go here blah blah blah end class Customer < Person # Customer table has all the fields it needs # Customer specific methods go here blah blah blah end if Users and Customers really, really are different entities. You could also go the STI route... -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Thanks Tim, On May 18, 9:15 am, Tim Lovett <timo...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Are customers different than users? > Can customers also be users? > > I''d say you should probably just put the customers and users table into one. > You can create a table that links off of users that links them to orders > (customers) if the need arises. Or if they are two separate roles can always > have a flag that denotes it.Users could be customers but customers are definitely not necessarily users. Imagine a POS application, you have users that effectively use the application and you have customers to whom you sell products/ services. Those customers'' info can be stored in the DB. Some of the characteristics will be similar but their functions are entirely different.> The normalization is fine on the name breaking it out to its pieces. > > The problem arises though when you try to break off users and customers that > if they are the same person they likely will need to reinsert all of their > previous information when signing up. It just adds messiness to the database > and makes it harder to associate their information with the user without > somehow getting the original table''s name id back to the new one. And > imagine if they have two separate name ids... then they have to go and > update their values in both tables.I am adding also a CUSTOMER_TYPES table because there will be several user types, including an EMPLOYEE type. How we''ll handle that will be a separate issue and we''ll probably provide a way of copying the information from the users table to the customers table.> I''d personally suggest you combine all three tables unless there is a clear > distinction between customers and users,I believe there is a clear distinction. Thanks. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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 have used STI before and although it works I am not that crazy about it and in this case I don''t think it can be applied because one person *could* be both a user and a customer. I like the concept of the abstract Person model, though. I didn''t think about that one and I think it''s a good idea. Any links to a sample of how to use abstract classes? I''ve never used them before. Thanks! On May 18, 9:26 am, Ar Chron <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> pepe wrote: > > > I have thought about factoring out the name to a separate model: > > Most of this decision depends on how you intend to treat your Users and > Customers. Perhaps you just have people, with a flag attribute on each, > or people with related models of Customer-specific info and > User-specific info. Is a User really different from a Person (will you > track people who aren''t users or customers - if so, then Person isn''t > abstract)? But only you know the answers to these questions. > > I think of names (first, last, middle, full, nickname, etc) as > attributes of some model, not a model of its own... > > Sounds like you *could* have a base (abstract) class of Person, then do > > class Person < ActiveRecord::Base > self.abstract_class = true > # common methods go here > end > > class User < Person > # User table has all the fields it needs > # User specific methods go here > blah blah blah > > end > > class Customer < Person > # Customer table has all the fields it needs > # Customer specific methods go here > blah blah blah > end > > if Users and Customers really, really are different entities. > > You could also go the STI route... > -- > 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. > For more options, visit this group athttp://groups.google.com/group/rubyonrails-talk?hl=en.-- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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.
You could argue for and against this kind of abstraction. By factoring it out you reduce the number of fields in the database, you reduce repetition, you have a model to put name related logic in if there is any and it is easier to implement changes in the naming convention later. The draw back is that the data structure becomes a bit more complex, which will affect most the CRUD operations on those tables. It''s probably overkill for only two tables, but could be worth it if there are a lot of them. My attitude is always to try new things if you''ve never done them before. That way, the next time you face a similar design issue, you have some first hand experience to base the decision on. Try it. If it doesn''t work out at all, it wouldnt be too difficult to refactor. I would structure the models different, using a polymorphic association: class Name < ActiveRecord::Base belongs_to :nameable, :polymorphic => true end class User < ActiveRecord::Base has_one :name, :as => :nameable end class Customer < ActiveRecord::Base has_one :name, :as => :nameable end On May 18, 3:15 pm, Tim Lovett <timo...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Are customers different than users? > Can customers also be users? > > I''d say you should probably just put the customers and users table into one. > You can create a table that links off of users that links them to orders > (customers) if the need arises. Or if they are two separate roles can always > have a flag that denotes it. > > The normalization is fine on the name breaking it out to its pieces. > > The problem arises though when you try to break off users and customers that > if they are the same person they likely will need to reinsert all of their > previous information when signing up. It just adds messiness to the database > and makes it harder to associate their information with the user without > somehow getting the original table''s name id back to the new one. And > imagine if they have two separate name ids... then they have to go and > update their values in both tables. > > I''d personally suggest you combine all three tables unless there is a clear > distinction between customers and users, > > Tim > > > > On Tue, May 18, 2010 at 8:58 AM, pepe <P...-gUAqH5+0sKL6V6G2DxALlg@public.gmane.org> wrote: > > I''m working on application where several tables > > (users,customers,other...) will have the same name structure (prefix, > > first, middle, last, suffix). > > > I have thought about factoring out the name to a separate model: > > > *** Migrations *** > > class CreateNames < ActiveRecord::Migration > > def self.up > > create_table :names do |t| > > t.string :prefix > > t.string :first > > t.string :middle > > t.string :suffix > > end > > end > > end > > > class CreateUsers < ActiveRecord::Migration > > def self.up > > create_table :users do |t| > > t.integer :name_id > > # other columns here > > end > > end > > > class CreateCustomers < ActiveRecord::Migration > > def self.up > > create_table :customers do |t| > > t.integer :name_id > > # other columns here > > end > > end > > > *** Models *** > > class Name < ActiveRecord::Base > > has_one :user > > has_one :customer > > end > > > class User < ActiveRecord::Base > > belongs_to :name > > end > > > class Customer < ActiveRecord::Base > > belongs_to :name > > end > > > I believe the concept is sound but I am concerned about a couple of > > things. I know that search capabilities by user/customer/other are > > coming and name searches are going to be in the mix. > > > Am I putting myself into a bad situation by going this way? > > Are named scopes going to be my friends? > > What would be the best/fastest way to query the database with this > > design? > > Am I abstracting the DB too much? > > > Thanks > > > Pepe > > > -- > > 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > > To unsubscribe from this group, send email to > > rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org<rubyonrails-talk%2Bunsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org> > > . > > For more options, visit this group at > >http://groups.google.com/group/rubyonrails-talk?hl=en. > > -- > 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. > For more options, visit this group athttp://groups.google.com/group/rubyonrails-talk?hl=en.-- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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.
On Tue, May 18, 2010 at 06:23:57AM -0700, pepe wrote:> I am doing the same with addresses, although I understand the problem is > different because a person can have more than one address but not more > than 1 name (except for AKAs) or if the person is Jason Bourne... ;)Someone in the witness protection program might have more than one name. Then, there are actors with birth names and stage names. And what about someone with a name like María Rosario Pilar Martínez Molina Baeza? Is that one name, or many? Sorry, I couldn''t resist. :-) -- Kevin http://www.RawFedDogs.net http://www.WacoAgilityGroup.org Bruceville, TX What''s the definition of a legacy system? One that works! Errare humanum est, ignoscere caninum. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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.
On May 18, 10:08 am, Sharagoz <shara...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> You could argue for and against this kind of abstraction. By factoring > it out you reduce the number of fields in the database, you reduce > repetition, you have a model to put name related logic in if there is > any and it is easier to implement changes in the naming convention > later. The draw back is that the data structure becomes a bit more > complex, which will affect most the CRUD operations on those tables. > It''s probably overkill for only two tables, but could be worth it if > there are a lot of them.There is a third table (for now): EMERGENCY_CONTACTS that will contain the name of the emergency contact person and his/her phone. This is actually the one that started me thinking about the name abstraction. I realized that this table will have only the name of the person and a phone number and I had just created the other 2 tables also with a name in them.> My attitude is always to try new things if you''ve never done them > before. That way, the next time you face a similar design issue, you > have some first hand experience to base the decision on. > Try it. If it doesn''t work out at all, it wouldnt be too difficult to > refactor.That''s usually my attitude too but this time I am under a time crunch and need to get things done asap. I would rather not have to go back and redo a bunch of changes to the DB and to code when I figure out that the design is flawed.> I would structure the models different, using a polymorphic > association: > class Name < ActiveRecord::Base > belongs_to :nameable, :polymorphic => true > end > > class User < ActiveRecord::Base > has_one :name, :as => :nameable > end > > class Customer < ActiveRecord::Base > has_one :name, :as => :nameable > endNot used polymorphic associations yet. Could be a good way of going. Thanks a lot -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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.