has_many through association with collection_check_boxes question not working at create action (kinda)
Testing has_many through association, I want to do that Product has many Category, and Product has many Certificate. Both associations are two-way, and the setups of them, as below, are pretty much identical.
During the new product creation phase, category_ids are passed through and it works fine; however, what I found odd is that if I only select certificates, it fails. I get the following error message saying it's invalid.
#<ActiveModel::Errors:0x007fcb651d32a0 @base=#<Admin::Product id: nil, name: nil, model: "1", country: "1", document: "1", inquiry: nil, permalink: "pro1", feature: nil, specification: nil, dimensions: nil, description: nil, created_at: nil, updated_at: nil>, @messages={ :certificates=>["translation missing: en.activerecord.errors.models.admin/product.attributes.certificates.invalid"]}, @details={ :certificates=>[{:error=>:invalid}]}>
Also, if I skip selecting certificates during creataion and later add that after the new product is created, it works.
I looked through the codes over and over but no luck figuring out why.
Product model
class Product < ApplicationRecord
validates :name, :model, :country, :permalink, presence: true
validates :permalink, uniqueness: true
has_many :category_product_relations, dependent: :destroy
has_many :categories, through: :category_product_relations
has_many :certificate_product_relations, dependent: :destroy
has_many :certificates, through: :certificate_product_relations
extend Mobility
translates :name, type: :string, locale_accessors: [:en, :"zh-TW"]
translates :feature, :specification, :dimensions, :description, type: :text, locale_accessors: [:en, :"zh-TW"]
end
Category model
class Category < ApplicationRecord
validates :name_zh_tw, presence: true, uniqueness: true
validates :permalink, presence: true, uniqueness: true
has_many :category_product_relations
has_many :products, through: :category_product_relations
extend Mobility
translates :name, type: :string, locale_accessors: [:en, :"zh-TW"]
end
CategoryProductRelation
class CategoryProductRelation < ApplicationRecord
belongs_to :category
belongs_to :product
end
Certificate model
class Certificate < ApplicationRecord
validates :name_zh_tw, :image, presence: true
has_many :certificate_product_relations
has_many :products, through: :certificate_product_relations
mount_uploader :image, ImageUploader
extend Mobility
translates :name, type: :string, locale_accessors: [:en, :"zh-TW"]
end
CertificateProductRelation
class CertificateProductRelation < ApplicationRecord
belongs_to :certificate
belongs_to :product
end
Products controller
before_action :find_product, only: [:edit, :update, :destroy]
def new
@admin_product = Admin::Product.new
@admin_product.build_image
@admin_product.build_metum
end
def create
@admin_product = Admin::Product.new(product_params)
if @admin_product.save
redirect_to admin_products_path, notice: "New product created"
else
flash[:alert] = "Somthing Went Wrong: "
render :new
end
end
def edit
end
def update
if @admin_product.update(product_params)
redirect_to admin_products_path, notice: "Product updated"
else
flash[:alert] = "Somthing Went Wrong: "
render :edit
end
end
private
def find_product
@admin_product = Admin::Product.find_by(id: params[:id])
end
def product_params
params.require(:admin_product).permit( ...omit...{category_ids: []}, {certificate_ids: []})
end
form
<%= form_for @admin_product do |f| %>
----- omit -----
<%= f.collection_check_boxes :category_ids, Category.all, :id, :name %>
<%= f.collection_check_boxes :certificate_ids, Certificate.all, :id, :name %>
----- omit -----
<% end %>