I am building an eCommerce website using rails 5 and activeadmin gem to manage my dashboard. I have a product and a category model in a many to one relationship.
class Product < ApplicationRecord
before_destroy :not_referenced_by_any_line_item
belongs_to :category
has_many :line_items, dependent: :destroy
has_many :reviews, dependent: :destroy
def self.search(search)
all.where("lower(title) LIKE :search", search: "%#{search}%")
end
private
def not_referenced_by_any_line_item
unless line_items.empty?
errors.add(:base, "line items present")
throw :abort
end
end
end
class Category < ApplicationRecord
has_many :products, dependent: :destroy
def self.search(search)
all.where("lower(category_name) LIKE :search", search: "%#{search}%")
end
end
I then registered the models to the activeadmin dashboard as below
ActiveAdmin.register Product do
permit_params :title, :description, :availability,
:price, :photo_link, :category_id, :advert, :pictureOne,
:pictureTwo, :pictureThree
end
ActiveAdmin.register Category do
permit_params :category_name, :photos
end
I can now select a product category on the project form when creating a product but the problem is, instead of a category name or any other field to display on the project category form input field so that you know exactly which category you are selecting,an abject is being displayed making it difficult to know which category you are selecting. display of dropdown of product category input form field:
ActiveAdmin's default functionality is to look for a name
field on a given model when deciding what to render as the record's identifier. If the model doesn't have a name
field, ActiveAdmin doesn't how else to let you which record you're dealing with besides being able to show you a stringified mess of the location where that record is in memory (It's the same string you'd get if you did Category.first.to_s
in the console).
To get the ActiveAdmin to recognize the name, you have to override the default edit form it creates for you so you can customize the select label.
You'll add all the fields you want to be editable to the form. When you get adding the input for the category, you specify that you want that field to be a select and you can customize the select's label, like so:
# app/admin/product.rb
ActiveAdmin.register Product do
permit_params :title, :description, :availability,
:price, :photo_link, :category_id, :advert, :pictureOne,
:pictureTwo, :pictureThree
form do |f|
f.inputs do
# Add a form input for the category
#
# This approach also allows you to specify which categories you
# allow to be selected, in the "collection" attribute.
#
# Inside the "map" call, you have the proc return an array with the first item
# in the array being the name of the category (the label for the select)
# and the second item being the category's ID (the select's value)
f.input :category_id, label: 'Category', as: :select, collection: Category.all.map{ |c| [c.category_name, c.id]}
# Then add other inputs
f.input :title
f.input :description
f.input :availability
# ...
# (Add f.input for the rest of your fields)
end
f.actions
end
end
You'll follow similar methods when you need to render the name a category in other places in ActiveAdmin.
If it's not too much trouble, you'll probably be better off renaming category_name
on your Category model to just name
. That way, you'll be fighting with ActiveAdmin a lot less and won't need to make customizations like this as much.