Editing many-to-many relations in Activeadmin

activeadmin, has-many-through, many-to-many, ruby-on-rails

Solution

This is a pretty late answer :) but I actually have encountered kind of a similar issue in one of my projects...I had to add keywords/tags to two different models, but they could share them. At first I did just like you, and it was creating a record for each time you "attach" a keyword/tag to a model.

A better way to handle it is to use a tagging system. And I achieved a pretty neat system by combining two really good gems: 'acts-as-taggable-on' (https://github.com/mbleigh/acts-as-taggable-on) and 'select2-rails' (https://github.com/argerim/select2-rails)

In my own project, I actually did something similar to you and created a model just to have a list of all the appropriate keywords I wanted. But 'act-as-taggable-on' doesn't necesarilly requires a list of accepted keywords...so you can create them on the fly, and it will automatically handle duplicates, counts etc.

'select2-rails' just allows you to have an nice interface to add and remove keywords in one field, rather than using checkboxes, select options, or a text input where you would have to manually separate your string with commas or any separators.

If anyone need more details on how I implemented all, I would be more than glad to provide more code .. but the documentation for both of them are pretty straightforward!

EDIT: Well, I have a feeling some code would actually be useful :)

Bundle install both gem in your Gemfile

gem 'acts-as-taggable-on'
gem 'select2-rails'

In your `Area` model, you could add the following and do something like

class Area < ActiveRecord::Base
    # .. your code

    attr_accessible :area_keyword_list

    acts_as_taggable_on :area_keywords
end

And in your ActiveAdmin file

ActiveAdmin.register Area do

    form do |f|
      f.inputs do
        # .. whatever fields you have
        f.input :area_keyword_list,
          :as => :select,
          :multiple => :true,
          :collection => # here either a list of accepted keyword..or just left open,
          :input_html => { :class => "multiple-select" }
      end
    end
end

and the JS for `select2` is quite simple ...

$(".multiple-select").select2();

Voilà !

Problem

I am looking for a way to edit/add keywords related to an article, inline in Activeadmin. I have defined a simple many-to-many setup: ``` class Area < ActiveRecord::Base has_many :area_keywords has_many :keywords, :through => :area_keywords accepts_nested_attributes_for :keywords, :reject_if => :all_blank, :allow_destroy => true end class AreaKeyword < ActiveRecord::Base belongs_to :area belongs_to :keyword end class Keyword < ActiveRecord::Base has_many :area_keywords has_many :areas, :through => :area_keywords end ``` I would like to add and edit the keywords in en Area form, so I setup this in Aciveadmin: ``` ActiveAdmin.register Area do form do |f| f.inputs "Area details" do f.input :title f.input :description end f.has_many :keywords do |k| if k.object.nil? k.input :word, :label => 'Keyword' else k.input :word, :label => k.object.word k.input :_destroy, :as => :boolean, :label => "delete" end end end end ``` This works as expected. But if I add the same Keyword to two different areas, the Keyword will just be created twice. When entering a new keyword (in the Area form), I would like it to automatically create a relation to an existing keyword, or create a new keyword, if it does not exist. What would be the best way to go about it?

Original source