Reputation: 2795
Hi have a products model in my Rails 3.1 app which looked like this:
+----------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| type | text | YES | | NULL | |
| title | text | YES | | NULL | |
| description | text | YES | | NULL | |
| price | text | YES | | NULL | |
| img_src | text | YES | | NULL | |
| source | text | YES | | NULL | |
| sr_id | text | YES | | NULL | |
| categories | text | YES | | NULL | |
+----------------+---------------+------+-----+---------+----------------+
I created a Categories_Products using the following migration (Did not create a model):
class CreateCategoriesProducts < ActiveRecord::Migration
def change
create_table :categories_products, :id => false do |t|
t.references :product
t.text :categories
t.timestamps
end
end
end
1) How do I set up my products form so that when Categories text_field is filled in, it will update the join table I just created. I deleted the categories column from the products table.
2) The whole reason I did this is because I initially had multiple Category ID's in a single field, and needed to break them up so that I could easily perform distinct counts and such. The user needs to be able to add multiple categories per a product, how can I tell Rails to save each category added into a new row in the db?
Upvotes: 2
Views: 1553
Reputation: 35219
A Product can have multiple Categories, and a Category can refer to multiple Products, right? If so, you want to create a third association table, let's call it product_categories
, and use the standard Rails idioms to support it:
# file: app/models/product.rb
class Product < ActiveRecord::Base
has_many :categories, :through => :product_categories
has_many :product_categories, :dependent => :destroy
end
# file: app/models/category.rb
class Category < ActiveRecord::Base
has_many :products, :through => :product_categories
has_many :product_categories, :dependent => :destroy
end
# file: app/models/product_category.rb
class ProductCategory < ActiveRecord::Base
belongs_to :product
belongs_to :category
end
... and your tables / migrations:
# file: db/migrate/xxx_create_products.rb
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
...
t.timestamps
end
end
end
# file: db/migrate/xxx_create_categories.rb
class CreateCategories < ActiveRecord::Migration
def change
create_table :categories do |t|
t.string :name
t.timestamps
end
end
end
# file: db/migrate/xxx_create_product_categories.rb
class CreateProductCategories < ActiveRecord::Migration
def change
create_table :product_categories do |t|
t.references :product
t.references :category
t.timestamps
end
end
end
This way, "adding multiple categories per product" becomes easy:
my_product.categories.create(:name => "toy")
This will create a Category named "toy" as well as the ProductCategory that associates my_product and that new Category. If you want the full description, this Guide is a place to start.
Upvotes: 3