Skip to content

Instantly share code, notes, and snippets.

@Fustrate
Last active January 3, 2016 05:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fustrate/8420084 to your computer and use it in GitHub Desktop.
Save Fustrate/8420084 to your computer and use it in GitHub Desktop.
module LoadResources
module ClassMethods
def load_resource(resource_class, options = {})
filter_options = options.slice :only, :except, :if, :unless
resource_options = options.except :only, :except, :if, :unless
send(:before_filter, filter_options) do |controller|
ResourceBuilder.new(controller, resource_class, resource_options)
.send(:load_resource)
end
end
def load_and_authorize_resource(resource_class, options = {})
send(:authorize_actions_for, resource_class)
filter_options = options.slice :only, :except, :if, :unless
resource_options = options.except :only, :except, :if, :unless
send(:before_filter, filter_options) do |controller|
ResourceBuilder.new(controller, resource_class, resource_options)
.send(:load_and_authorize_resource)
end
end
end
def self.included(base)
base.extend ClassMethods
base.helper_method :permitted_param?
end
# Check if a parameter is permitted for the current user.
#
# This is useful in view forms to only show fields based on ability.
def permitted_param?(parameter)
permitted_params.include? parameter
end
def permitted_params
@permitted_params ||= begin
model_name = self.class.to_s
.sub('Controller', '')
.underscore
.gsub('/', '_')
.singularize
if respond_to?("#{ model_name }_params", true)
send("#{ model_name }_params")
else
[]
end
end
end
class ResourceBuilder
def initialize(controller, resource_class, options = {})
@controller = controller
@resource_class = resource_class
@params = controller.params
@options = options
end
def instance_variable(value)
@controller.instance_variable_set("@#{ instance_var }", value)
end
def load_resource
resource = find_resource
if resource
resource = update_resource(resource)
instance_variable resource
end
end
def load_and_authorize_resource
resource = find_resource
if resource
resource = update_resource(resource)
@controller.send(:authorize_action_for, resource)
instance_variable resource
end
end
def update_resource(resource)
if update_actions.include? @params[:action].to_sym
resource.assign_attributes(permitted_parameters)
end
resource
end
def find_resource
case @params[:action].to_sym
when *collection_actions
@resource_class.all
when *find_actions
@resource_class.find(@params[:id])
when *create_actions
@resource_class.new
else
false
end
end
def instance_var
@instance_var ||= if collection_actions.include?(@params[:action].to_sym)
(@options[:as] || resource_name).to_s.pluralize
else
(@options[:as] || resource_name)
end
end
def resource_name
@resource_name ||= @resource_class.to_s.gsub('::', '_').underscore
end
def authorize_resource(resource)
authorize_action_for resource
end
def build_resource
# params_method = @resource_class
end
def collection_actions
%i[index] + [@options[:collection_actions]].flatten
end
def find_actions
%i[show edit update destroy] + [@options[:find_actions]].flatten
end
def create_actions
%i[new create] + [@options[:create_actions]].flatten
end
# Actions which we'll assign attributes for
def update_actions
%i[create update] + [@options[:update_actions]].flatten
end
# Load params safely through Rails 4's Strong Parameters
def permitted_parameters
if @params[resource_name] &&
@controller.respond_to?("#{ resource_name }_params", true)
@params.require(resource_name)
.permit(*@controller.send("#{ resource_name }_params"))
end
end
end
end
if defined? ActionController::Base
ActionController::Base.class_eval do
include LoadResources
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment