Created
August 27, 2021 05:59
-
-
Save tjbarker/daeb4ee12012b52a79aeaaacb3801a13 to your computer and use it in GitHub Desktop.
active admin, polymorphic drop down
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# this is a helper method to provide setters for polymorphic relationships in active admin forms | |
# attribute_name: name that record knows polymorphic relationship as | |
# actions: the active record actions that should use this setter, defaults to setter being implemented before create and update | |
def polymorphic_attribute_set(attribute_name, actions: [:before_create, :before_update]) | |
klass = config.resource_class | |
foreign_key = klass.reflect_on_all_associations.find { |ref| ref.name == attribute_name }.association_foreign_key | |
setter = lambda do |rec| | |
record = ApplicationRecord.identifier_to_record(params[klass.name.snakecase][foreign_key]) | |
resource.send("#{attribute_name}=", record) | |
end | |
actions.each { |action| send(action, &setter) } | |
end | |
# this is a helper to provide a polymorphic dropdown that will interact with the above polymorphic attribute setter | |
# f: is the form in which the select is to be placed | |
# key: is the name of the polymorphic attribute on the record | |
# options: are the records to be selected from | |
# selected: is the record to prefill selection with | |
# display: is the method to call on each option to display in the dropdown | |
# other options for the select can also be appended as named params | |
def polymorphic_select(f, key, options, selected: nil, display: :to_s, **opts) | |
options_list = options.flatten.map { |opt| [opt.send(display), ApplicationRecord.record_to_identifier(opt)] } | |
f.input key, as: :select, collection: options_for_select(options_list, selected&.identifier), **opts | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ActiveAdmin.register Foo do | |
permit_params :bar | |
# will set bar on record before create and update | |
polymorphic_attribute_set :bar | |
form do |f| | |
# adds drop down with list of all Baz and Buzz instances for selection as resource's bar | |
polymorphic_select(f, :bar, [Baz.all, Buzz.all], selected: resource.bar) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
IDENTIFICATION_JOINER = '>><<'.freeze | |
def record_to_identifier(record) | |
[record.class.name, record.id].join(IDENTIFICATION_JOINER) | |
end | |
# WARNING: may raise NameError if identifier cannot be constantized | |
def self.identifier_to_record(identifier) | |
return if identifier.blank? | |
record_klass_string, record_id = identifier.split(IDENTIFICATION_JOINER) | |
record_klass = record_klass_string.constantize | |
record_klass.find_by(record_klass.primary_key => record_id) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment