module ActsAsControllerFor
module Base
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_controller_for(model, options = {})
# Store the model and options for this controller in class variables for usage in actions
class_variable_set :@@model, model
class_variable_set :@@options, options
# Load and authorize (via +cancan+ gem) if set to
if options[:load_and_authorize]
load_and_authorize_resource(options[:load_and_authorize].is_a?(Hash) ? options[:load_and_authorize] : nil)
end
# Define actions...
include InstanceMethods
end
end
module InstanceMethods
# block - the optional block defines the value of the models instance variable set for this action
# GET /models
# GET /models.xml
# GET /models.json
def index(&block)
model = self.class.send :class_variable_get, :@@model
options = self.class.send :class_variable_get, :@@options
inst_var_ref = "@#{model.name.underscore.pluralize}".to_sym
inst_var_p_ref = "@paginated_#{model.name.underscore.pluralize}".to_sym
if block
instance_variable_set options[:paginate] ? inst_var_p_ref : inst_var_ref, yield
else
if !options[:load_and_authorize]
instance_variable_set inst_var_ref, model.all
end
if options[:paginate]
instance_variable_set inst_var_p_ref, instance_variable_get(inst_var_ref).paginate(:page => params[:page], :per_page => model.per_page)
end
end
respond_to do |format|
format.html # index.html.(erb|haml)
format.xml { render :xml => instance_variable_get(inst_var_ref) }
format.json { render :json => instance_variable_get(inst_var_ref) }
end
end
# block - the optional block defines the value of the models instance variable set for this action
# GET /models/:id
# GET /models/:id.xml
# GET /models/:id.json
def show(&block)
model = self.class.send :class_variable_get, :@@model
options = self.class.send :class_variable_get, :@@options
inst_var_ref = "@#{model.name.underscore}".to_sym
if block
instance_variable_set inst_var_ref, yield
else
if !options[:load_and_authorize]
instance_variable_set inst_var_ref, model.find(params[:id])
end
end
respond_to do |format|
format.html # show.html.(erb|haml)
format.xml { render :xml => instance_variable_get(inst_var_ref) }
format.json { render :json => instance_variable_get(inst_var_ref) }
end
end
# GET /models/new
def new
model = self.class.send :class_variable_get, :@@model
options = self.class.send :class_variable_get, :@@options
inst_var_ref = "@#{model.name.underscore}".to_sym
if !options[:load_and_authorize]
instance_variable_set inst_var_ref, model.new
end
end
# block - the optional block defines the value of the models instance variable set for this action
# GET /models/:id/edit
def edit(&block)
model = self.class.send :class_variable_get, :@@model
options = self.class.send :class_variable_get, :@@options
inst_var_ref = "@#{model.name.underscore}".to_sym
if block
instance_variable_set inst_var_ref, yield
else
if !options[:load_and_authorize]
instance_variable_set inst_var_ref, model.find(params[:id])
end
end
end
# block - the optional block defines the value of the model instance variable set for this action
# POST /models
# POST /models.xml
# POST /models.json
def create(&block)
model = self.class.send :class_variable_get, :@@model
options = self.class.send :class_variable_get, :@@options
inst_var_ref = "@#{model.name.underscore}".to_sym
if block
instance_variable_set inst_var_ref, yield
else
if !options[:load_and_authorize]
instance_variable_set inst_var_ref, model.new(params[model.name.to_sym])
end
end
respond_to do |format|
if instance_variable_get(inst_var_ref).save
format.html { redirect_to(send("admin_#{model.name.underscore.pluralize}_path"), :notice => "#{model.name} was successfully created.") }
format.xml { render :xml => instance_variable_get(inst_var_ref), :status => :created, :location => [:admin, instance_variable_get(inst_var_ref)] }
format.json { render :json => instance_variable_get(inst_var_ref), :status => :created, :location => [:admin, instance_variable_get(inst_var_ref)] }
else
format.html { render :action => "new" }
format.xml { render :xml => instance_variable_get(inst_var_ref).errors, :status => :unprocessable_entity }
format.json { render :json => instance_variable_get(inst_var_ref).errors, :status => :unprocessable_entity }
end
end
end
# block - the optional block defines the hash of attributes to update the edited model with. Defaults to params[:model]
# PUT /models/:id
# PUT /models/:id.xml
# PUT /models/:id.json
def update(&block)
model = self.class.send :class_variable_get, :@@model
options = self.class.send :class_variable_get, :@@options
inst_var_ref = "@#{model.name.underscore}".to_sym
if !options[:load_and_authorize]
instance_variable_set inst_var_ref, model.find(params[:id])
end
respond_to do |format|
if instance_variable_get(inst_var_ref).update_attributes(block ? yield : params[model.name.underscore])
format.html { redirect_to(send("admin_#{model.name.underscore.pluralize}_path"), :notice => "#{model.name} was successfully updated.") }
format.xml { head :ok }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => instance_variable_get(inst_var_ref).errors, :status => :unprocessable_entity }
format.json { render :json => instance_variable_get(inst_var_ref).errors, :status => :unprocessable_entity }
end
end
end
# DELETE /models/1
# DELETE /models/1.xml
# DELETE /models/1.json
def destroy
model = self.class.send :class_variable_get, :@@model
options = self.class.send :class_variable_get, :@@options
inst_var_ref = "@#{model.name.underscore}".to_sym
if !options[:load_and_authorize]
instance_variable_set inst_var_ref, model.new(params[model.name.to_sym])
end
instance_variable_get(inst_var_ref).destroy
respond_to do |format|
format.html { redirect_to(send("admin_#{model.name.underscore.pluralize}_path"), :notice => "#{model.name} was destroyed.") }
format.xml { head :ok }
format.json { head :ok }
end
end
end
end
end