I am new to programming & rails and there's something I dont fully understand. I am creating an app with
product has_many categories
category has_many products
If I understand correctly I need to create a join table products_categories which has a product_id
& a category_id
. First do I also need a model for this table ? if yes I guess it would look like this :
class CategoryProduct < ActiveRecord::Base
belongs_to :category
belongs_to :product
end
and the other models in product.rb :
class Product < ActiveRecord::Base
has_many :category_products
has_many :categories, through: :category_product
has_attached_file :picture,
styles: { medium: "300x300>", thumb: "100x100>" }
validates_attachment_content_type :picture,
content_type: /\Aimage\/.*\z/
validates :price, presence: { message: "Merci d'indiquer le prix du produit" }
validates :name, presence: { message: "Merci d'indiquer le nom du produit" }
validates :weight, presence: { message: "Merci d'indiquer le poids du produit" }
validates :description, presence: { message: "Merci d'écrire une description du produit " }
end
and in category.rb
class Category < ActiveRecord::Base
has_many :category_products
has_many :products, through: :category_product
validates :name, presence: { message: "Merci d'indiquer le nom de la catégorie" }
end
Now let's say I want to create a product and while I am creating it, specify as many categories as I want for this product from the categories' list.
So far this was my Product/new.html.slim in my views :
div class="container marged-top"
div class= "col-xs-12 col-md-offset-3 col-md-5 bigmarge"
div class="panel panel-default"
div class= "panel-heading"
h4 Création Produit
div class= "panel-body"
=simple_form_for @product, html: { multipart: true } do |t|
= t.error_notification
= t.input :name, label: 'Nom'
= t.input :description, label: 'Description', required: true
= t.input :price, label: 'Prix', required: true
= t.input :weight, label: 'Poids', required: true
= t.label :picture
= t.file_field :picture
= t.association :categories, as: :check_boxes
= t.button :submit, value: "Valider", class: "btn-success marge-bas"
This was a simple form for my Product instance. I guess I need to have a form for a CategoryProduct now ? How do I have to change that if I want the user to be able to add as many categories he wants to the product while he's creating it ?
Here's my migration file for category_product table :
class CreateTableCategoriesProducts < ActiveRecord::Migration
def change
create_table :categories_products do |t|
t.references :product, index: true
t.references :category, index: true
end
add_foreign_key :categories_products, :categories
add_foreign_key :categories_products, :products
end
end
I renamed the previous table with the following migration file :
class RenameTableCategoriesProducts < ActiveRecord::Migration
def self.up
rename_table :categories_products, :category_products
end
def self.down
rename_table :category_products, :categories_products
end
end
I am getting the following error on the simple_form in product/new.html.slim :
undefined method `klass' for nil:NilClass
The code breaks here :
= t.association :categories, as: :check_boxes
so I guess my associations arent still quite right