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
-~----------~----~----~----~------~----~------~--~---