My relationship with ActiveScaffold
Last Updated on: July 22, 2020
Like most long relationships, we started on a bad note.
The very first day, ActiveScaffold choked on me and stopped firing Ajax requests. Turned out, I had forgotten to gift her a “require jquery_ujs” in the application.js.
But alas, the gift failed to appease her for long.
Now I wanted to nest AS view, in my custom views. What’s wrong with that you would say, but AS seems to get all jealous.
I gave her the normal render:
= render :active_scaffold => '/user/user_details', :constraints => { :user_id => @user.id }, :label => ''
But no, she just wouldn’t listen and couldn’t allow me to have it my way.
Turns out, it is the “render_component_vho” gem that she needed. Well, AS, you could have just told me that instead of throwing all those tantrums and unhelpful error to me.
The next milestone in our relationship was to have our inheritance ready. Single Table Inheritance, piece of cake.. actually yes!
Basically, the index view of the parent STI controller could have member actions such as edit, show, delete link to the corresponding specific STI controller.
Helped keep things neat and clean. And I must thank this guy for the relationship advice.
Next came nested AS views (i.e AS views within themselves). This was actually easier than nesting AS views inside a custom views. For once, AS behaved normally and rationally and the views were just like nested association between two db’s
The child model needed just a “nested” keyword :
class AccountDepositsController < CustomerServiceController
active_scaffold AccountDeposit do |config|
config.actions = [ :list, :search, :show, :create, :nested]
end
end
And it could be consumed in the parent controller like :
class AccountsController < ApplicationController
active_scaffold Account do |config|
config.columns = [:id, :user_id, :customer, :account_email, :balance, :account_deposits]
end
end
Sweet, ain’t it!
Now that we were all cozy and settled, it was time to add some spice. In came some kinky DSLs. Our models had tons of state machines, and it was a pain to tell AS about each of them and configure action links for all events. She seem to get all tired, so this is what we agreed on.
A simple one line dsl in the controller :
has_state_machine_events
And the definition of the DSL was something on this lines :
require 'active_support/concern'
module ProtectedActionBinder
extend ActiveSupport::Concern
included do
end
module ClassMethods
def has_state_machine_events state_machines = nil
state_machines = [state_machines].flatten.map(&:to_sym) unless state_machines.nil?
controller_model.state_machines.each do |key, value|
if state_machines.nil? || state_machines.include?(key)
events = value.events.collect{|e| e.name.to_s}
secured_events_by_state_machine[key] = events
has_secured_active_scaffold_action(events) if events.present?
end
end
end
def has_secured_active_scaffold_action action_list
action_list = [action_list].flatten
generate_active_scaffold_action_links(action_list)
generate_controller_methods(action_list)
end
def generate_active_scaffold_action_links action_links
config_links = self.active_scaffold_config.action_links
return if config_links.blank?
action_links.each do |event|
config_links.add "#{event}", type: :member,
method: :post,
refresh_on_close: true,
label: event.gsub('_',' ').to_s.titleize
end
end
def generate_controller_methods action_list
model=self.active_scaffold_config.model
action_list.each do |action|
define_method action.to_sym do
obj = model.find(params[:id])
if obj.present?
obj.send(action.to_sym)
render text: "Done"
else
render text: "Not Authorized"
end
end
end
end
end
end
Well, so far so good. The relationship ain’t over and am sure we are gonna have many more adventures along the way. Love you AS 🙂