class Product include SimplyStored::Couch property :name property :code property :price, type: Float #belongs_to :product_category has_and_belongs_to_many :product_categories, storing_keys: false belongs_to :supplier # direct! category is an aid has_many :product_orders attr_protected :supplier_id validates :name, presence: true validates :supplier_id, presence: true validates :price, presence: true, numericality: true view :by_supplier_id_and_id, key: [:supplier_id, :_id] after_save :persist_product_category_ids def product_category_ids=(ids) @product_category_ids = ids.select(&:present?) is_dirty end private def persist_product_category_ids @product_category_ids ||= [] existing_product_categories = product_categories # do nothing if nothing has changed return if @product_category_ids == existing_product_categories.map(&:id) # clear removed product categories existing_product_categories.reject{|pc| @product_category_ids.include?(pc.id) }.each{|pc| pc.remove_product(self) } # Add product to newly added product categories database.load(@product_category_ids - existing_product_categories.map(&:id)).each do |product_category| product_category.add_product(self) end end end