Hi, I''m having a bit of trouble with my first Rails app. ---- I have two tables: create_table :items do |t| t.column :created_at, :timestamp t.column :user_id, :int t.column :text, :text end create_table :users do |t| t.column :user_id, :int t.column :name, :string end ---- I''m trying to use the "user_id" field to link both tables, with each user "has_many" items, and items "belong_to" users. ---- In my user.rb: class User < ActiveRecord::Base has_many :items, :foreign_key => ''user_id'' end And in my item.rb: class Item < ActiveRecord::Base belongs_to :user, :foreign_key => ''user_id'' end ---- In my controller, I can get the effect I want by doing something like this: @user = User.find(:first, :conditions => "name = ''#{params[:id]}''") @items = Item.find(:all, :conditions => "user_id = ''#{@user.user_id}''") But I was hoping that by adding ", :include => :tweets" to the @user call, that I would be able to automatically grab the associated items. Sorry if this is a very basic question, but I haven''t found any documentation all day and I''m sure I''m just missing something conceptually. Thanks -- 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 -~----------~----~----~----~------~----~------~--~---
Robert Walker
2008-Apr-19 01:09 UTC
Re: has_many and belongs_to with non-primary foreign keys
First of all your relationship is invalid. In relational databases there are three valid types of relationships, which are one-to-one, one-to-many, and many-to-many. In Rails a one-to-one relationship is actually represented by a validated one-to-many relationship. In other words as far as the database is concerned it is a one-to-many. On the Rails side you use has_one in place of the has_many. This simply limits the one-to-many so the many side allows only one associated object. User: has_one :item Item: belongs_to :user At one-to-many is similar to a one-to-one except it uses has_many like this: User: has_many :items Item: belongs_to :user The third type of relationship requires what is called a "join table" and is called a many-to-many relationship: User: has_and_belongs_to_many :items Item: has_and_belongs_to_many :users This requires a third table that contains two foreign keys making up two one-to-many relationships: create_table :items do |t| t.column :created_at, :timestamp t.column :text, :text end create_table :users do |t| t.column :name, :string end create_table :items_users do |t| t.column :item_id, :integer t.column :user_id, :integer You never join two table between two foreign keys. There is no way for the database to track the relationship. All relations are based on one of these three basic types. Also note that Rails provide has_many :through for many-to-many relationships where the joining table has it''s own model object. This is used to expose additional columns inside the join table that are used to track information related to both side of the many-to-many association. An example of this would be Suppliers and Products. You may want to track things like the last purchase price of a specific product that was purchased from a specific supplier. This value would be stored inside the join table. Then the join table would have it own model object for accessing that information. Call it maybe ProductSupplier. Then you could do something like my_product_supplier.last_purchase_price, where my_product_supplier is an instance of the class ProductSupplier. Hope this helps. On Apr 18, 4:27 pm, Tom Fadial <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Hi, > > I''m having a bit of trouble with my first Rails app. > > ---- > > I have two tables: > create_table :items do |t| > t.column :created_at, :timestamp > t.column :user_id, :int > t.column :text, :text > end > create_table :users do |t| > t.column :user_id, :int > t.column :name, :string > end > > ---- > > I''m trying to use the "user_id" field to link both tables, with each > user "has_many" items, and items "belong_to" users. > > ---- > > In my user.rb: > class User < ActiveRecord::Base > has_many :items, :foreign_key => ''user_id'' > end > > And in my item.rb: > class Item < ActiveRecord::Base > belongs_to :user, :foreign_key => ''user_id'' > end > > ---- > > In my controller, I can get the effect I want by doing something like > this: > @user = User.find(:first, :conditions => "name = ''#{params[:id]}''") > @items = Item.find(:all, :conditions => "user_id = ''...@user.user_id}''") > > But I was hoping that by adding ", :include => :tweets" to the @user > call, that I would be able to automatically grab the associated items. > > Sorry if this is a very basic question, but I haven''t found any > documentation all day and I''m sure I''m just missing something > conceptually. > > Thanks > -- > 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 think you have an extra ''user_id'' column that''s causing some confusion. The User table does not need it. By default, the create_table call is going to generate a users table with a auto- incrementing ''id'' column. Unless you do something explicit to override the convention (you haven''t) then Rails is going to use that field as the primary key/id. By convention, a table referring to another table has a foreign key named after the class to which it refers. That means your items table should have a user_id column to refer to the User class (as it does). Having followed the conventions you can just use the has_many/ belongs_to macros without modification. On Apr 18, 4:27 pm, Tom Fadial <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Hi, > > I''m having a bit of trouble with my first Rails app. > > ---- > > I have two tables: > create_table :items do |t| > t.column :created_at, :timestamp > t.column :user_id, :int > t.column :text, :text > end > create_table :users do |t| > t.column :user_id, :int > t.column :name, :string > end > > ---- > > I''m trying to use the "user_id" field to link both tables, with each > user "has_many" items, and items "belong_to" users. > > ---- > > In my user.rb: > class User < ActiveRecord::Base > has_many :items, :foreign_key => ''user_id'' > end > > And in my item.rb: > class Item < ActiveRecord::Base > belongs_to :user, :foreign_key => ''user_id'' > end > > ---- > > In my controller, I can get the effect I want by doing something like > this: > @user = User.find(:first, :conditions => "name = ''#{params[:id]}''") > @items = Item.find(:all, :conditions => "user_id = ''...@user.user_id}''") > > But I was hoping that by adding ", :include => :tweets" to the @user > call, that I would be able to automatically grab the associated items. > > Sorry if this is a very basic question, but I haven''t found any > documentation all day and I''m sure I''m just missing something > conceptually. > > Thanks > -- > 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-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Tom Fadial
2008-Apr-19 01:30 UTC
Re: has_many and belongs_to with non-primary foreign keys
Robert Walker wrote:> First of all your relationship is invalid. In relational databases > there are three valid types of relationships, which are one-to-one, > one-to-many, and many-to-many.Ok, thanks for the overview, there weren''t nearly enough basic HowTo''s for this. I''m still unsure of what type of relationship I should have then.> You never join two table between two foreign keys. There is no way for > the database to track the relationship. All relations are based on one > of these three basic types.Yeah, I figured that was probably my problem. The issue is that the user_id is already specified (as something like: ''11384739'') and the regular "id" begins at 1 and auto_increments.> Hope this helps.It does, thank you. AndyV wrote:> I think you have an extra ''user_id'' column that''s causing some > confusion. The User table does not need it. By default, the > create_table call is going to generate a users table with a auto- > incrementing ''id'' column. Unless you do something explicit to > override the convention (you haven''t) then Rails is going to use that > field as the primary key/id. > > By convention, a table referring to another table has a foreign key > named after the class to which it refers. That means your items table > should have a user_id column to refer to the User class (as it does). > > Having followed the conventions you can just use the has_many/ > belongs_to macros without modification.I added the extra user_id column in the users table because each user already has a specified id, as does each item (and each user has_many items). What I was attempting to do was display all of the items for a given user by matching the "user_id" columns of each table. I''m basically trying to configure the models so that this call [@items = Item.find(:all, :conditions => "user_id = ''#{@user.user_id}''")] can be accessed natively like @user.items. I hope that made sense and thanks for your help so far! -- 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 -~----------~----~----~----~------~----~------~--~---
Maybe Matching Threads
- Once I added this HABTM, one of my 'through' relationships, on a non-habtm model, seems to have broke?
- has_many :through with Single Table inheritance
- 2 belongs_to to the same parent table
- acts_as_versioned and getting authors
- Self-referential has_many :through relationship