I would like to ask how to customize active admin.
I`m making my own blog and creating admin page using active admin gem.
This has many to many relationship with article and tag through article_tag table.
What I want to do is to add tag from article panel and I was able to show tag view in article panel, but it is not working fine.(I can`t update or remove tag after save once)
http://localhost:3000/admin/articles/new
image
I made the many to many relation with Article and Tag model like this.
article.rb
class Article < ActiveRecord::Base
has_many :article_tags
has_many :tags, through: :article_tags
accepts_nested_attributes_for :article_tags, :allow_destroy => true
end
tag.rb
class Tag < ActiveRecord::Base
has_many :article_tags
has_many :articles, through: :article_tags
end
article_tag.rb
class ArticleTag < ActiveRecord::Base
belongs_to :article
belongs_to :tag
end
And I customized active admin like this.
ActiveAdmin.register Article do
permit_params :title, :description, :url, :image_url, :media, article_tags_attributes: [:article_id, :tag_id, :name, :_destroy, :_edit]
form do |f|
# f.semantic_errors *f.object.errors.keys
f.inputs "Admin Details" do
f.input :title
f.input :description
f.input :url
f.input :image_url
f.input :media
f.input :publish
end
f.inputs "Articles" do
f.has_many :article_tags do |t|
t.input :tag
end
end
f.actions
end
end
But after I saved the article with tag once I can`t update tag or delete tag...
Does anyone know how to fix this?
You forgot to permit :id attribute of article_tag object. It is passed when updating/deleting existing nested object.
ActiveAdmin.register Article do
permit_params :title, :description, :url, :image_url, :media, article_tags_attributes: [:id, :article_id, :tag_id, :name, :_destroy, :_edit]
...
end
Related
I have something like this:
class Actor < ActiveRecord::Base
attr_accessible :name, :actor_movie_relationships_attributes
validates :name
has_many :actor_movie_relationships, autosave: true
has_many :movies, through: :actor_movie_relationships
accepts_nested_attributes_for :actor_movie_relationships
end
And:
class ActorMovieRelationship < ActiveRecord::Base
belongs_to :movie
belongs_to :actor
validates :movie, :actor, presence: true
end
Since Actor can have many movies, I'd like to paginate the ActiveAdmin form that is used to administer these relationships.
Currently I have this form (which is NOT paginated):
form do |f|
tabs do
tab 'Actor' do
f.inputs 'Basic Information' do
f.semantic_errors *f.object.errors.keys
f.input :name
f.input :deleted
end
end
tab 'Movies' do
f.inputs 'List of movies' do
f.has_many :actor_movie_relationships, heading: '', new_record: 'Add a Movie', allow_destroy: true do |a|
a.input :Movie, collection: Movie.dropdown_names_map.call
end
end
end
end
f.actions
end
Any idea how to add pagination to Movies in this form?
When I use ActiveAdmin to edit one Agency, I can select a City and associates it to the Agency. The city is linked to the Agency, but the city is all the times duplicated in the database.
My models:
# agency.rb
class Agency < ActiveRecord::Base
has_many :agency_cities
has_many :cities, through: :agency_cities
accepts_nested_attributes_for :cities, allow_destroy: true
end
# city.rb
class City < ActiveRecord::Base
has_many :agency_cities
has_many :agencies, through: :agency_cities
end
# AgencyCity.rb
class AgencyCity < ActiveRecord::Base
belongs_to :agency
belongs_to :city
end
I read the doc of Activeadmin and added the [:id] permit_parameter, but I still have the problem, I'm very confused.
# admin/agency.rb
ActiveAdmin.register Agency do
permit_params :name, :picture,
cities_attributes: [:id, :name, :description, :_destroy]
form do |f|
f.inputs "Agencies" do
f.input :picture, as: :file
f.input :creation_date, label: 'Creation Date'
f.input :name, label: 'Name'
end
end
f.inputs do
f.has_many :cities do |k|
k.input :name, label: 'City',
as: :select,
collection: City.all.map{ |u| "#{u.name}"}
k.input :_destroy, as: :boolean
end
end
f.actions
end
You are trying to associate the existing cities with an agency, so, you should do it this way:
ActiveAdmin.register Agency do
permit_params city_ids: [] # You need to whitelist the city_ids
form do |f|
f.inputs "Agencies" do
f.input :picture, as: :file
f.input :creation_date, label: 'Creation Date'
f.input :name, label: 'Name'
f.input :cities, as: :check_boxes, checked: City.pluck(&:id) # this will allow you to check the city names that you want to associate with the agency
end
end
end
This will allow you to associate the selected cities to the corresponding agency without creating (duplicating) new cities in the database. I think this is what you are looking for :-)
You can check in the generated html that the option values in the city select input are the name of the city (not the id).
Try this way: collection: City.all.map{ |u| [u.name, u.id]}
Some reference: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html
I have in my Rails application BlogPosts and BlogCategories, and a BlogPostCategorization table to join them together. So
class BlogCategory < ActiveRecord::Base
attr_accessible :name, :created_at, :updated_at, :blog_post_id
validates :name, presence: true, uniqueness: true
has_many :blog_post_categorizations
has_many :blog_posts, :through => :blog_post_categorizations
accepts_nested_attributes_for :blog_posts, allow_destroy: true
end
class BlogPost < ActiveRecord::Base
attr_accessible :body, :created_at, :updated_at, :image_url, :title
validates :body, :image_url, :title, presence: true
validates :title, uniqueness: true
has_many :blog_post_categorizations
has_many :blog_categories, :through => :blog_post_categorizations
accepts_nested_attributes_for :blog_categories, allow_destroy: true
end
class BlogPostCategorization < ActiveRecord::Base
belongs_to :blog_post
belongs_to :blog_category
end
Now through ActiveAdmin, I want to be able to create a new blog post, and create categories for this blog post. I have
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs "Blog Post" do
f.input :title
f.input :body, as: :html_editor
f.input :image_url
end
f.inputs "Blog Categories" do
f.has_many :blog_post_categorizations do |s|
s.input :blog_category
end
end
f.actions
end
But when I try to access the active admin page for new Blog Post, I get a rails error message saying "undefined method `new_record?' for nil:NilClass" on the line where
f.has_many :blog_post_categorizations do |s|
What am I doing wrong/missing?
Additionally, included below is the blog_category data that's being sent in the params hash of the POST request
"blog_categories_attributes"=>{"1408936652467"=>{"name"=>"cooking"}, "1408936656066"=>{"name"=>"eat"}}
I think this part:
f.inputs "Blog Categories" do
f.has_many :blog_post_categorizations do |s|
s.input :blog_category
end
end
should be:
f.inputs "Blog Categories" do
f.has_many :blog_categorys do |s|
s.input :name
end
end
EDIT
Taking into account your another question on this issue I would recommend a (I hope) good workaround. Since strong_parameters are by default used in Rails 4 and higher, and you are on Rails 3.2.17, let us make your app use it.
So there are the steps:
install gem 'strong_parameters';
set to false config.active_record.whitelist_attributes in config/application.rb;
include ActiveModel::ForbiddenAttributesProtection in the BlogPost and BlogCategory models;
get rid of all attr_accessible calls.
Having all this done you can whitelist all params in private method, like so:
private
def blog_post_params
params.require(:blog_post).permit(#all the params here)
end
And in #create action use BlogPost.new(blog_post_params) (same in other model(s), where you use the included module). Now you can benefit from strong_parameters.
In ActiveAdmin BlogPost model whitelist all permitted parameters as:
permit_params :body, :created_at, :updated_at, :image_url, :title, blog_categories_attributes: [:id, :name, :_destroy, :blog_post_id]
and in controller
controller do
def permitted_params
params.permit blog_posts: [:body, :created_at, :updated_at, :image_url, :title, blog_categories_attributes: [:id, :name, :_destroy, :blog_post_id]]
end
end
Take a more precise look at strong_params usage in documentation. And also double check typos/wrong namings/underscores (because I presumed some things).
Good luck!
I have a many-to-many relationship set up between blog posts and blog categories using the has_many :through relationship and I am having trouble creating a blog post resource through active admin.
class BlogPost < ActiveRecord::Base
attr_accessible :body, :created_at, :updated_at, :image_url, :title
validates :body, :image_url, :title, presence: true
validates :title, uniqueness: true
has_many :blog_post_categorizations
has_many :blog_categories, :through => :blog_post_categorizations
accepts_nested_attributes_for :blog_categories, allow_destroy: true
end
class BlogCategory < ActiveRecord::Base
attr_accessible :id, :name, :created_at, :updated_at
validates :name, presence: true, uniqueness: true
has_many :blog_post_categorizations
has_many :blog_posts, :through => :blog_post_categorizations
accepts_nested_attributes_for :blog_posts, allow_destroy: true
end
class BlogPostCategorization < ActiveRecord::Base
belongs_to :blog_post
belongs_to :blog_category
end
Now as for my activeadmin formtastic setup, I have:
ActiveAdmin.register BlogPost do
form do |f|
f.inputs "Blog Post" do
f.input :title
f.input :body, as: :html_editor
f.input :image_url
end
f.inputs "Blog Categories" do
f.has_many :blog_categories do |s|
s.input :name
end
end
f.actions
end
end
This allows the new blog post page to load successfully, but when I attempt to submit the new post with categories attached, it results in a "Can't mass-assign protected attributes: blog_categories_attributes" error.
I suspect that my models are set up properly, but the form in ActiveAdmin is not. Any ideas as to how I can correctly set up the form?
Additionally, included below is the blog_category data that's being sent in the params hash of the POST request
"blog_categories_attributes"=>{"1408936652467"=>{"name"=>"cooking"}, "1408936656066"=>{"name"=>"eat"}}
Using Rails version 3.2
So I have the following models:
Image:
class Image < ActiveRecord::Base
has_many :product_images
has_many :products, :through => :product_images
attr_accessible :asset, :name, :description, :product_ids, :file_content_type, :is_boolean
accepts_nested_attributes_for :product_images
has_attached_file :asset
end
ProductImage:
class ProductImage < ActiveRecord::Base
belongs_to :product
belongs_to :image
attr_accessible :is_thumbnail
end
and Product:
class Product < ActiveRecord::Base
has_many :images, :through => :product_images
has_many :product_images
attr_accessible :name, :description, :thumbnail, :searchTerms, :group_ids, :upload_file_ids
end
Now what I would like to do on the images form is display a checkbox for all the products and then another checkbox for the is_thumbnail attribute
I have had a look into using simple_fields_for but this will only display if the product has already been added. Is there a way to do this?
<%= f.simple_fields_for(:product_images) do |builder| %>
<%= builder.input :is_thumbnail %>
<%= builder.association :products, include_blank: false %>
<% end %>
I'm not very familiar with simple_fields however building form inputs base on an instance will only allow you to "represent" that instance.
This means that you could print all already associated products using
builder.association :products
but if you want to print all products in your database you will need to fetch them, loop and display them in your form.