Skip to content

Commit

Permalink
Merge 44113c9 into cc178ad
Browse files Browse the repository at this point in the history
  • Loading branch information
chumakoff committed Aug 20, 2016
2 parents cc178ad + 44113c9 commit 232ec80
Show file tree
Hide file tree
Showing 7 changed files with 369 additions and 10 deletions.
21 changes: 17 additions & 4 deletions lib/active_admin/controller_action.rb
@@ -1,12 +1,25 @@
module ActiveAdmin
class ControllerAction
attr_reader :name
attr_reader :name, :http_verb

def initialize(name, options = {})
@name, @options = name, options
@name = name.to_sym
@http_verb = resolve_http_verb(options)
end

def remove_http_verbs(verbs)
self.http_verb = http_verb - verbs
end

def http_verb
@options[:method] ||= :get
private

attr_writer :http_verb

def resolve_http_verb(options)
method = options[:method]
return [:get] unless method

Array(method).map { |m| m.downcase.to_sym }.uniq
end
end
end
8 changes: 5 additions & 3 deletions lib/active_admin/resource.rb
Expand Up @@ -10,6 +10,7 @@
require 'active_admin/resource/scope_to'
require 'active_admin/resource/sidebars'
require 'active_admin/resource/belongs_to'
require 'active_admin/resource/controller_actions'

module ActiveAdmin

Expand Down Expand Up @@ -63,7 +64,8 @@ def initialize(namespace, resource_class, options = {})
@resource_class_name = "::#{resource_class.name}"
@options = options
@sort_order = options[:sort_order]
@member_actions, @collection_actions = [], []
@member_actions = ControllerActions.new
@collection_actions = ControllerActions.new
end
end

Expand Down Expand Up @@ -107,11 +109,11 @@ def resource_quoted_column_name(column)

# Clears all the member actions this resource knows about
def clear_member_actions!
@member_actions = []
@member_actions = ControllerActions.new
end

def clear_collection_actions!
@collection_actions = []
@collection_actions = ControllerActions.new
end

# Return only defined resource actions
Expand Down
43 changes: 43 additions & 0 deletions lib/active_admin/resource/controller_actions.rb
@@ -0,0 +1,43 @@
module ActiveAdmin
class Resource
class ControllerActions
def initialize
@actions = []
end

def items
copy
end

# Adds a new action to the collection.
# Don't allow add actions with the same name and http method,
# in order to avoid routes duplication.
def <<(new_action)
actions.each do |action|
next if action.name != new_action.name

new_action.remove_http_verbs(action.http_verb)
return if new_action.http_verb.blank?
end

actions << new_action
end

def each(&block)
copy.each(&block)
end

def size
actions.size
end

private

attr_accessor :actions

def copy
actions.dup
end
end
end
end
2 changes: 2 additions & 0 deletions lib/active_admin/resource_controller.rb
Expand Up @@ -5,6 +5,7 @@
require 'active_admin/resource_controller/streaming'
require 'active_admin/resource_controller/sidebars'
require 'active_admin/resource_controller/resource_class_methods'
require 'active_admin/resource_controller/action_verb_combiner.rb'

module ActiveAdmin
# All Resources Controller inherits from this controller.
Expand All @@ -22,6 +23,7 @@ class ResourceController < BaseController
include Streaming
include Sidebars
extend ResourceClassMethods
extend ActionVerbCombiner

def self.active_admin_config=(config)
if @active_admin_config = config
Expand Down
79 changes: 79 additions & 0 deletions lib/active_admin/resource_controller/action_verb_combiner.rb
@@ -0,0 +1,79 @@
module ActiveAdmin
class ResourceController < BaseController
module ActionVerbCombiner
private

# Add behaviour to an existing action, depending on http method,
# when the same action name is specified.
#
# For example:
#
# ActiveAdmin.register Post do
# member_action :comments, method: :get do
# @post = Post.find(params[:id]
# @comments = @post.comments
# end
#
# member_action :comments, method: :post do
# @post = Post.find(params[:id]
# @post.comments.create!(comment_params)
# end
# end
#
# Will be equivalent to:
#
# ActiveAdmin.register Post do
# member_action :comments, method: [:get, :post] do
# if request.post?
# @post = Post.find(params[:id]
# @post.comments.create!(comment_params)
# else
# @post = Post.find(params[:id]
# @comments = @post.comments
# end
# end
# end
#
def add_behaviour_to_action(action_name, http_verbs, &block)
old_method_name = add_alias_for_old_behaviour(action_name)
new_method_name = add_method_for_new_behaviour(action_name, &block)

define_method(action_name) do
if request.method_symbol.in?(http_verbs)
send new_method_name
else
send old_method_name
end
end
end

def add_alias_for_old_behaviour(action_name)
method_name = resolve_method_name(action_name, "old")
alias_method method_name, action_name

private method_name

method_name
end

def add_method_for_new_behaviour(action_name, &block)
method_name = resolve_method_name(action_name, "new")
define_method method_name, &block

private method_name

method_name
end

def resolve_method_name(action_name, postfix)
next_name = "#{action_name}_#{postfix}"

while private_method_defined?(next_name) || method_defined?(next_name)
next_name = "#{next_name}_#{postfix}"
end

next_name
end
end
end
end
16 changes: 13 additions & 3 deletions lib/active_admin/resource_dsl.rb
Expand Up @@ -111,14 +111,24 @@ def csv(options={}, &block)
# You can treat everything within the block as a standard Rails controller
# action.
#
def action(set, name, options = {}, &block)
set << ControllerAction.new(name, options)
def action(actions_set, name, options = {}, &block)
action = ControllerAction.new(name, options)
name, http_verb = action.name, action.http_verb
actions_set << action

title = options.delete(:title)

controller do
callback = ActiveAdmin::Dependency.rails >= 4 ? :before_action : :before_filter
send(callback, only: [name]) { @page_title = title } if title
define_method(name, &block || Proc.new{})

block ||= Proc.new {}

if public_method_defined? name
add_behaviour_to_action(name, http_verb, &block)
else
define_method(name, &block)
end
end
end

Expand Down

0 comments on commit 232ec80

Please sign in to comment.