Skip to content

Instantly share code, notes, and snippets.

@olegantonyan
Last active October 4, 2015 10:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olegantonyan/c1c3d5edce92dfa039de to your computer and use it in GitHub Desktop.
Save olegantonyan/c1c3d5edce92dfa039de to your computer and use it in GitHub Desktop.
CrudResponder - DRYing controller actions. Now in gem https://github.com/olegantonyan/crud_responder
# lib/crud_responder.rb
module CrudResponder
include ActionView::Helpers::TextHelper
protected
def crud_respond(object, options = {})
method = options.fetch(:method, method_by_caller(caller))
success_url = options.fetch(:success_url) { default_redirect_url(method, object) }
error_action = options.fetch(:error_action) { default_render_action(method, object) }
if perform(caller, object, method)
redirect_to success_url
else
render error_action
end
end
private
def object_index_url object
polymorphic_url(object.class)
rescue NoMethodError
nil
end
def object_url object
polymorphic_url(object)
rescue NoMethodError
nil
end
def default_redirect_url(method, object)
if method == :destroy
object_index_url(object)
else
object_url(object)
end || :back
end
def default_render_action(method, object)
if object.persisted?
:edit
else
:new
end
end
def caller_name(_caller)
_caller[0][/`.*'/][1..-2]
end
def method_by_caller(_caller)
if caller_name(_caller) =~ /destroy/
:destroy
else
:save
end
end
def perform(_caller, object, method)
ok = object.public_send(method)
t_key = "flash.actions.#{action_by_caller(_caller)}.#{ok ? 'notice' : 'alert'}"
if ok
flash_success I18n.t(t_key, resource_name: resoucre_name_by_object(object))
else
flash_error I18n.t(t_key, resource_name: resoucre_name_by_object(object), errors: object.errors.full_messages.to_sentence)
end
ok
end
def action_by_caller(_caller)
case caller_name(_caller)
when /destroy/
:destroy
when /update/
:update
when /create/
:create
else
"unknown_action_from_#{caller_name(_caller)}".to_sym
end
end
def resoucre_name_by_object(object)
object.class.to_s
end
def flash_success msg
flash[:notice] = truncate_message(msg)
end
def flash_error msg
flash[:alert] = truncate_message(msg)
end
def truncate_message msg
truncate(msg.to_s, length: 256, escape: false)
end
end
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
include CrudResponder
def create
@post = Post.new(post_params)
crud_respond @post # will be saved inside `crud_respond` + appropriate flash message will be shown + redirecte or render appropriate action
end
def update
@post = Post.find(params[:id])
@post.assign_attributes(post_params)
crud_respond @post
end
def destroy
@post = Post.find(params[:id])
crud_respond @post
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment