Skip to content

Instantly share code, notes, and snippets.

@chrisbloom7
Last active September 10, 2019 11:40
Show Gist options
  • Save chrisbloom7/82713f9847187b3f2be7 to your computer and use it in GitHub Desktop.
Save chrisbloom7/82713f9847187b3f2be7 to your computer and use it in GitHub Desktop.
Dynamic enum field values in nested association forms in Rails Admin
# app/models/change.rb
class Change < ActiveRecord::Base
belongs_to :changeset, inverse_of: :changed_fields
validates :changeset, presence: true, associated: true
validates :field, presence: true, uniqueness: {scope: :changeset_id}, inclusion: { in: :field_enum }
def field_enum
if changeset.try(:model).present?
changeset.model_attributes
else
all_attributes
end
end
private
def all_attributes
::MODELS.collect{|k,h| h["attributes"]}.flatten.uniq.sort
end
end
# app/controllers/changes_controller.rb
class ChangesController < ApplicationController
before_filter :authenticate_user!
def get_attributes_for
attributes = Change.new(changeset: Changeset.new(model: params[:model])).field_enum
render json: attributes
end
end
# app/models/changeset.rb
class Changeset < ActiveRecord::Base
has_many :changed_fields, class_name: "Change", dependent: :destroy, inverse_of: :changeset
accepts_nested_attributes_for :changed_fields, :allow_destroy => true
validates :model, presence: true, inclusion: { in: :model_enum }
def model_enum
::MODELS.keys.sort
end
def model_attributes
::MODELS[model].try(:[], "attributes").try(:sort) || []
end
end
# config/routes.rb
Rails.application.routes.draw do
# ...
get 'changes/attributes_for/:model' => 'changes#get_attributes_for'
# ...
end
# app/assets/javascripts/rails_admin/custom/ui.coffee
$ = jQuery
updateAttributes = (selects = $("select[id^=changeset_changed_fields_attributes]")) ->
model = $('#changeset_model').val()
$.get("/changes/attributes_for/" + model).done (values) ->
elements = []
$.each values, (idx, value) ->
elements.push($("<option></option>").attr("value", value).text(value))
selects.each ->
select = $(this)
selected = select.val()
select.filteringSelect("destroy").find("option:gt(0)").remove().end().append(elements).filteringSelect().val(select)
$(document).on 'change', '#changeset_model', (event) ->
updateAttributes()
$(document).on 'nested:fieldAdded', 'form', (content) ->
updateAttributes(content.field.find("select[id^=changeset_changed_fields_attributes]"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment