Configure the label of Active Admin has_many

10,244

Solution 1

To set has_many header you can use

f.has_many :images, heading: 'My images' do |i|
  i.input :src, label: false
end

See here

Solution 2

Looking at ActiveAdmin tests("should translate the association name in header"), there may be another way of doing this. Use your translation file.

If you look at ActiveAdmin has_many method (yuck!!! 46 lines of sequential code), it uses ActiveModel's human method.

Try adding this to your translation file

en:
  activerecord:
    models:
      document:
        one: Document Version
        other: Document Versions

Solution 3

One quick hack is that you can hide the h3 tag through its style.

assets/stylesheets/active_admin.css.scss

    .has_many {
      h3 {
        display: none;
      }}

This will hide any h3 tag under a has_many class.

Solution 4

You can customise the label of the "Add..." button by using the new_record setting on has_many. For the heading label you can use heading:

f.has_many :documents,
           heading: "Document Versions",
           new_record: "Add new Document Version" do |d|
  d.input :file, :as => :file
end

Solution 5

Sjors answer is actually a perfect start to solving the question. I monkeypatched Active Admin in config/initializers/active_admin.rb with the following:

module ActiveAdmin
 class FormBuilder < ::Formtastic::FormBuilder
  def titled_has_many(association, options = {}, &block)
   options = { :for => association }.merge(options)
   options[:class] ||= ""
   options[:class] << "inputs has_many_fields"

   # Set the Header
   header = options[:header] || association.to_s

   # Add Delete Links
   form_block = proc do |has_many_form|
     block.call(has_many_form) + if has_many_form.object.new_record?
                                  template.content_tag :li do
                                    template.link_to I18n.t('active_admin.has_many_delete'), "#", :onclick => "$(this).closest('.has_many_fields').remove(); return false;", :class => "button"
                                  end
                                else
                                end
  end

  content = with_new_form_buffer do
    template.content_tag :div, :class => "has_many #{association}" do
      form_buffers.last << template.content_tag(:h3, header.titlecase) #using header
      inputs options, &form_block

      # Capture the ADD JS
      js = with_new_form_buffer do
        inputs_for_nested_attributes  :for => [association, object.class.reflect_on_association(association).klass.new],
                                      :class => "inputs has_many_fields",
                                      :for_options => {
                                        :child_index => "NEW_RECORD"
                                      }, &form_block
      end

      js = template.escape_javascript(js)
      js = template.link_to I18n.t('active_admin.has_many_new', :model => association.to_s.singularize.titlecase), "#", :onclick => "$(this).before('#{js}'.replace(/NEW_RECORD/g, new Date().getTime())); return false;", :class => "button"

      form_buffers.last << js.html_safe
    end
  end
  form_buffers.last << content.html_safe
  end
 end
end

Now in my admin file I call titled_has_many just like has_many but I pass in :header to override the use of the Association as the h3 tag.

f.titled_has_many :association, header: "Display this as the H3" do |app_f|
  #stuff here
end
Share:
10,244
Admin
Author by

Admin

Updated on June 05, 2022

Comments

  • Admin
    Admin almost 2 years

    Well I have a two models related with a on-to-many assoc.

    #models/outline.rb
        class Outline < ActiveRecord::Base
          has_many :documents
        end
    
    #models/document.rb
        class Document < ActiveRecord::Base
          belongs_to :outline
        end
    
    #admin/outlines.rb
        ActiveAdmin.register Outline do
          form do |f|
            f.inputs "Details" do
              f.input :name, :required => true
              f.input :pages, :required => true
              ...
              f.buttons
            end
            f.inputs "Document Versions" do 
              f.has_many :documents, :name => "Document Versions"  do |d|
                d.input :file, :as => :file
                d.buttons do
                  d.commit_button :title => "Add new Document Version"
                end
              end
            end
          end
        end
    

    Well as you can see in the admin/outlines.rb I already tried setting up the :name, in the has_many :documents, and the :title in the commit_button, but neither of that options work, I also tried with :legend, :title, and :label, instead of :name in the .has_many. Not working.

    This is the result of that code: Screenshot

    What I want to display is "Document Versions" instead of "Documents", and "Add new Document Version" instead of "Add new Document"

    If someone can have a solution it would be great

  • Szymon Przybył
    Szymon Przybył almost 12 years
    thanks dude! If I will get some time, I will try to apply that fix to active_admin repo
  • Szymon Przybył
    Szymon Przybył almost 12 years
    but there is another issue here - we can't rename "Add more Resources" button :/
  • Josh Kovach
    Josh Kovach about 11 years
    This is the easiest way to deal with changing the name of a class in your forms. Have all my upvotes.
  • Mike Doyle
    Mike Doyle about 10 years
    How is this not the top answer? It's so so so simple! Thanks.