Skip to content

Instantly share code, notes, and snippets.

@AlexanderMint
Last active December 4, 2022 15:31
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 AlexanderMint/b41c846a78067e67b1f80ea0f9bfdba4 to your computer and use it in GitHub Desktop.
Save AlexanderMint/b41c846a78067e67b1f80ea0f9bfdba4 to your computer and use it in GitHub Desktop.
Ruby on Rails default controller + pundit
module DefaultController
extend ActiveSupport::Concern
included do
before_action :load_collection, only: [:index]
before_action :generate_model, only: [:new]
before_action :create_model, only: [:create]
before_action :load_model, only: %i[edit update show destroy]
before_action :alias_variable_model, only: %i[index new create show edit update destroy]
end
def index; end
def new; end
def edit; end
def show; end
def create
if @model.save
flash_message :success, t('.success')
before_redirect_create if respond_to?(:before_redirect_create)
redirect_to redirect_options[:create]
else
render :new
end
end
def update
if @model.update(model_params)
flash_message :success, t('.success')
before_redirect_update if respond_to?(:before_redirect_update)
redirect_to redirect_options[:update]
else
render :edit
end
end
def destroy
if @model.destroy
flash_message :success, t('.success')
before_redirect_destroy if respond_to?(:before_redirect_destroy)
redirect_to redirect_options[:destroy]
else
render :edit
end
end
private
def load_collection
@collection = respond_to?(:collection) ? collection : class_model.page(params[:page])
end
def generate_model
@model = class_model.new
end
def create_model
model_params = respond_to?(:model_params) ? self.model_params : nil
@model = class_model.new(model_params)
end
def load_model
@model = class_model.find(params[:id])
end
def class_model
raise 'Not implemented'
end
def model_params
raise 'Not implemented'
end
def redirect_options
raise 'Not implemented'
end
def filter_params
params.require(:filter).permit(filter_fields)
end
def alias_variable_model
# Pundit
# autopolicy @collection || @model
new_model_name = @collection ? @collection.model_name.collection : @model.model_name.element
instance_variable_set("@#{new_model_name}", @collection || @model)
end
### Pundit ###
# def autopolicy(record)
# authorize module_name ? [module_name, record] : record
# end
# def module_name
# name = self.class.parent.name.underscore
# name == 'object' ? nil : name.to_sym
# end
end
Example:
class CompaniesController < ApplicationController
include DefaultController
def class_model
Company
end
def load_model
@model = class_model.find(params[:id])
end
def redirect_options
{
create: company_root_url(subdomain: @company.subdomain),
update: url_for(:companies),
destroy: url_for(:companies)
}
end
def before_redirect_create
current_user.create_role :manager, @company
end
def model_params
params.require(:company).permit(:name, :subdomain)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment