I was following the Ruby on Rails Guides Active Record Aossications plus some other threads on here, but not sure I'm setting it up right:
Products have many variety image sets (like for color, flavor, style) A product variety has only one image set (size--> color shirt)
So I think the associations should actually be:
Products
--has_many :product_varieties
--has_many :variety_image_sets, through: :product_varieties
Product Varieties
--belongs_to :product
--has_one :variety_image_set
Variety Image Sets
--belongs_to :product_variety
I got this setup idea from the Rails Guides example of documents, sections and paragraphs, but unfortunately it only works if I use has_many :variety_image_sets for Product Varieties.
my classes are as follows:
class Product < ApplicationRecord
belongs_to :product_category
has_many :product_varieties
has_many :variety_image_sets, through: :product_varieties
end
class ProductVariety < ApplicationRecord
belongs_to :product
has_many :variety_image_sets
end
class VarietyImageSet < ApplicationRecord
belongs_to :product_variety
end
For the Variety Image Set model, I have a product_variety:references in the migration.
I am able to create a Variety Image Set for each individual Product Variety, but I want it to be able to reuse the sets I a product (example, a a black shirt can have several sizes).
Now, moving on to the Collection Select: Once we have at least one Variety Image Set defined, can use a collection select when creating a new product variety.
This one works:
= form_with(model: [@product, product_variety]) do |form|
= form.collection_select(:variety_image_set_ids, VarietyImageSet.all, :id, :label, { prompt: true }, {multiple: false})
In my controller's product_variety_params:
def product_variety_params
params.require(:product_variety).permit(:size, :unit_amount, :current_inventory, :variety_image_set_ids)
end
If I try to change VarietyImageSet.all to variety.variety_image_sets, the select menu goes empty. Also, one Product variety already has one defined, and when I try to assign that one to a different variety, that other variety "steals" it from the first one, instead of both being assigned that variety image set.
Please advise. Thanks
UPDATE Per the suggestion in the first answer, I've updated the associations. I now create the Variety Image Sets as a nested resource of Product instead of under Product Variety. This works.
Now, I click on edit for the Product Variety and want to assign a Pariety Image Set to it using the collection_select:
= form.collection_select(:variety_image_sets_id, VarietyImageSet.all, :id, :label, { prompt: true }, {multiple: false}) with updated params: def product_variety_params params.require(:product_variety).permit(:size, :unit_amount, :current_inventory, :variety_image_sets_id) end
But, I get the error that "Variety Image Set Must Exist".
finally, VarietyImageSet.all will give me all of them, I want to filter them to just those belonging to the product. @product.variety_image_sets returns undefined method "variety_image_sets" though.
= form_with(model: [@product, product_variety]) do |form|
CodePudding user response:
You should use ProductVariety as the middle table with the following association:
class Product < ApplicationRecord
belongs_to :product_category
has_many :product_varieties
has_many :variety_image_sets, through: :product_varieties
end
class ProductVariety < ApplicationRecord
belongs_to :product
belongs_to :variety_image_sets
end
class VarietyImageSet < ApplicationRecord
has_many :product_variety
end
Now the Product table will have all your products. VarietyImageSet will have all varieties for products and the ProductVariety table will store which product have which variety.