Skip to content

Instantly share code, notes, and snippets.

@antillas21
Last active May 28, 2017 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save antillas21/1c3b5a88c87e5a05a099 to your computer and use it in GitHub Desktop.
Save antillas21/1c3b5a88c87e5a05a099 to your computer and use it in GitHub Desktop.
An excersie in removing duplication on CRUD Rails controllers. Inspired by the book Growing Rails Application in Practice
# app/controllers/admin/base.rb
class Admin::BaseController
include Admin::CRUDMethods
class NotImplementedError < StandardError; end
def index
list_resources
end
def new
build_resource
end
def create
build_resource(accepted_params)
save_resource
end
def show
load_resource(id_key)
end
def edit
load_resource(id_key)
end
def update
load_resource(id_key)
update_resource(accepted_params)
end
def destroy
delete_resource(id_key)
end
private
def model
fail(
NotImplementedError,
'Configure main ActiveRecord class to manage in this controller.'
)
end
def model_key
model.to_s.tableize.to_sym
end
def id_key
params[:id]
end
def model_fields
fail(
NotImplementedError,
'Configure permitted field names to pass to a record in this controller.'
)
end
def accepted_params
params.require(model_key).permit(model_fields)
end
def success_action
fail(
NotImplementedError,
'Configure what to do when saving/updating a record succeeds.'
)
end
def error_action(resource, view)
@resource = resource
flash[:error] = 'Something went wrong.'
render view
end
def destroy_success_action
fail(
NotImplementedError,
'Configure what to do when deleting a record succeeds.'
)
end
end
# app/controllers/admin/crud_methods.rb
module Admin
module CRUDMethods
def list_resources
@resources = model.load
end
def build_resource(attrs = {})
@resource = model.new(attrs)
end
def load_resource(id)
@resource = model.find(id)
end
def save_resource
if @resource.save
success_action('Successfully created resource.')
else
error_action(@resource, :new)
end
end
def update_resource(attrs)
if @resource.update_attributes(attrs)
success_action('Successfully updated resource.')
else
error_action(@resource, :edit)
end
end
def delete_resource(id)
load_resource(id)
@resource.destroy
destroy_success_action
end
end
end
# app/controllers/admin/books_controller.rb
class Admin::BooksController < Admin::BaseController
private
def model
Book
end
def model_fields
[:title, :author_name, :isbn, :price, :page_count, :etc]
end
def success_action(message)
redirect_to admin_book_path(@resource), notice: message
end
def destroy_success_action(message)
redirect_to admin_books_path, notice: message
end
end
# app/controllers/admin/movies_controller.rb
class Admin::MoviesController < Admin::BaseController
private
def model
Movie
end
def model_fields
[:title, :director_name, :upc, :genre, :duration, :etc]
end
def success_action(message)
redirect_to admin_movie_path(@resource), notice: message
end
def destroy_success_action(message)
redirect_to admin_movies_path, notice: message
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment