Hi, I am creating my databases and models and I need to use some relationships. I am very new at this so any help or info at all would be great. :) The concept is: There are three resources: people, items and tags. * An item belongs to one person, the creator. * A person can create many items. * An item can have many tags. * A tag can be used on many items. Here my models: ----------------------------------- /* models/item.rb */ class Item < ActiveRecord::Base belongs_to :person has_many :tags end ----------------------------------- /* models/person.rb */ class Person < ActiveRecord::Base has_many :items end ----------------------------------- /* models/tag.rb */ class Tag < ActiveRecord::Base /* should I use ''has_and_belongs_to_many'' here? */ end Here''s the migrations: ----------------------------------- /* db/migrate/1_create_items.rb */ class CreateItems < ActiveRecord::Migration def self.up create_table :items do |t| t.string :name t.belongs_to :person /* what should I put here to create a relation to tags? */ end end def self.down drop_table :items end end ----------------------------------- /* db/migrate/2_create_people.rb */ class CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :name /* do I need something here to create a relation to items? */ end end def self.down drop_table :people end end ----------------------------------- /* db/migrate/3_create_tags.rb */ class CreateTags < ActiveRecord::Migration def self.up create_table :tags do |t| t.string :name /* what should I put here to create a relation to items? */ end end def self.down drop_table :tags end end -- 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 -~----------~----~----~----~------~----~------~--~---
On Apr 10, 12:22 pm, Christoffer Brodd-reijer <rails-mailing- l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > * An item belongs to one person, the creator. > * A person can create many items. > * An item can have many tags. > * A tag can be used on many items. > > Here my models: > models/tag.rb */ > class Tag < ActiveRecord::Base > /* should I use ''has_and_belongs_to_many'' here? */ > endYou could use has and belongs to many or has many through. Either way you will need another table (the join table for the relationship between tags and items), the existing tables are fine as is. You might find http://guides.rubyonrails.org/association_basics.html helpful. Fred --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Frederick Cheung wrote:> On Apr 10, 12:22�pm, Christoffer Brodd-reijer <rails-mailing- > l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: >> end > You could use has and belongs to many or has many through. Either way > you will need another table (the join table for the relationship > between tags and items), the existing tables are fine as is. > You might find http://guides.rubyonrails.org/association_basics.html > helpful. > > FredI went with using a joint table ----------------------------------- /* db/migrate/3_create_tags.rb */ ... create_table :item_tags, :id => false do |t| t.integer :tag t.integer :item end ... Now I am coding the controller that creates the item. I am iterating through each tag that the user typed in and I want this to happen: * Create a new tag in the ''tags'' table if it does not already exists * Associate the tag and item by adding the pair to the ''item_tags'' table The idea here is that each tag should be only once in the tags table. Here''s the controller function so far: ----------------------------------- /* controllers/items_controller.rb */ def create for tag in tags.split('' '') match = Tag.find(:first, :conditions => "name = ''#{tag}''") unless match Tag.create(:name => tag) end /* make association here */ end end Problem is, I don''t know how to add the association in the controller. Also, am I doing the rest of the stuff right? Or maybe Rails can automate this whole process somehow? 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
You can shorten this part up by using Tag.find_or_create_by_name, one of the dynamic finder methods. And I''d add a generic warning to NEVER use #{} interpolation directly in anything you''re feeding to an AR conditions parameter, unless you want to relearn the lesson of little Bobby Tables... The final code will look something like: def create # find item, put in @item @item.tags = params[:tags].split('' '').map do |tag| Tag.find_or_create_by_name(tag) end # do whatever else end Alternatively, you could encapsulate this behavior in the Item model, using a virtual tags_attr or the like to do the parsing. I''d recommend that you take a look at some of the approaches taken by acts_as_taggable and it''s descendants. --Matt Jones On Apr 10, 11:24 am, Christoffer Brodd-reijer <rails-mailing- l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> The idea here is that each tag should be only once in the tags table. > Here''s the controller function so far: > > ----------------------------------- > /* controllers/items_controller.rb */ > def create > for tag in tags.split('' '') > match = Tag.find(:first, :conditions => "name = ''#{tag}''") > unless match > Tag.create(:name => tag) > end > > /* make association here */ > > end > end > > Problem is, I don''t know how to add the association in the controller. > Also, am I doing the rest of the stuff right? Or maybe Rails can > automate this whole process somehow? 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 -~----------~----~----~----~------~----~------~--~---