Skip to content

Instantly share code, notes, and snippets.

@xionon
Last active August 29, 2015 14:01
Show Gist options
  • Save xionon/5f8bcecd1d463a3c20e3 to your computer and use it in GitHub Desktop.
Save xionon/5f8bcecd1d463a3c20e3 to your computer and use it in GitHub Desktop.
class PostsController < ApplicationController
respond_to :html, :json
before_action :find_post, only: %i(show edit update destroy)
before_action :find_posts, only: %i(index)
def index
respond_with decorate(@posts)
end
def show
respond_with decorate(@post)
end
def new
respond_with Posts::Forms::New.new(post_params)
end
def edit
respond_with Posts::Forms::Edit.new( @post )
end
def create
respond_with Posts::Services::Create.new(post_params).save
end
def update
respond_with Posts::Services::Update.new( @post ).save
end
private
def post_params
params.require(:post).permit(:title, :body)
end
def find_post
@post = Posts::Queries::One.run( params[:id] )
end
def find_posts
@posts = Posts::Queries::All.run
end
def decorate(post_or_posts)
Posts::Decorators::Default.decorator_for(current_user).decorate(post_or_posts)
end
end
module Posts
module Decorators
class Default
include DecoratorBase
# sets up initializer, adds attr_accessor
decorates :post
### NOTE:
# Not sure if I like mixing in all the ActionView helpers or not, so #title and #body show
# two different possible styles
def title
# ActionView methods are included...?
# Would give access to #t(), #url_for as included methods...
h( self.post.title )
end
def body
# Or maybe ActionView methods are included in an associate?
# would give access to @view.t(), @view.url_for, etc...
@view.h( self.post.title )
end
end
# Special rendering for admin viewers
# Need some sort of decorator factory to determine which subclass is appropriate for a user
class Admin < Default
def title
super + @view.link_to( '[Edit]', edit_post_path(self.post) )
end
end
end
end
module Posts
module Forms
class Default
include FormsBase
# Sets up initializer, attr_accessor
models :post
# Basic virtus setup
attribute :title, String
attribute :body, String
end
# Rendered for posts/new
class New < Default
attribute :publish_immediately, Boolean
end
# posts/edit/:id just chooses the default
end
end
module Posts
module Jobs
# No default jobs. These are for Delayed::Job, Resque, Sidekiq, etc. Just providing a grab-bag space for these
end
end
module Posts
module Queries
class Default
# sets up attr_accessor :scoped
include QueryBase
# Sets self.scoped to Post.scoped, by default
scopes :post
end
class All < Default
# #run methods are factory-style shortcutted -- All.run == All.new.run
def run
self.scoped.all
end
end
class One < Default
def run( id )
# uses find_by_*, because it's Adequate :)
self.scoped.find_by_id(id)
end
end
end
end
module Posts
module Services
class Default
include ServiceBase
# sets up initializer, sets up attr_accessor, sets up default #save
serves :post
end
class Create < Default
end
class Update < Default
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment