mirror of
https://github.com/drapergem/draper
synced 2023-03-27 23:21:17 -04:00
Generators redux.
Lots of changes here: * rake draper:install no longer needed * don't generate an ApplicationGenerator by default ** If one exists, the generator respects it * Fixes #53
This commit is contained in:
parent
e2151cd27a
commit
9155e58f74
14 changed files with 72 additions and 147 deletions
|
@ -6,22 +6,30 @@
|
|||
## Quick Start
|
||||
|
||||
1. Add `gem 'draper'` to your `Gemfile` and `bundle`
|
||||
2. Run `rails g draper:install` to create the directory and `ApplicationDecorator`
|
||||
3. Run `rails g draper:decorator YourModel`
|
||||
4. Edit `app/decorators/[your_model]_decorator.rb` using:
|
||||
2. Run `rails g draper:decorator YourModel`
|
||||
3. Edit `app/decorators/[your_model]_decorator.rb` using:
|
||||
1. `h` to proxy to Rails/application helpers like `h.current_user`
|
||||
2. `[your_model]` to access the wrapped object like `article.created_at`
|
||||
5. Put common decorations in `app/decorators/application.rb`
|
||||
6. Wrap models in your controller with the decorator using:
|
||||
4. Wrap models in your controller with the decorator using:
|
||||
1. `.find` automatic lookup & wrap
|
||||
ex: `ArticleDecorator.find(1)`
|
||||
2. `.decorate` method with single object or collection,
|
||||
ex: `ArticleDecorator.decorate(Article.all)`
|
||||
3. `.new` method with single object
|
||||
ex: `ArticleDecorator.new(Article.first)`
|
||||
7. Output the instance methods in your view templates
|
||||
5. Output the instance methods in your view templates
|
||||
ex: `@article_decorator.created_at`
|
||||
|
||||
If you need common methods in your decorators, create an `app/decorators/application_decorator.rb`:
|
||||
|
||||
``` ruby
|
||||
class ApplicationDecorator < Draper::Base
|
||||
# your methods go here
|
||||
end
|
||||
```
|
||||
|
||||
and make your decorators inherit from it. Newly generated decorators will respect this choice and inherit from `ApplicationDecorator`.
|
||||
|
||||
## Watch the RailsCast
|
||||
|
||||
Ryan Bates has put together an excellent RailsCast on Draper based on the 0.8.0 release:
|
||||
|
|
|
@ -8,3 +8,14 @@ require 'draper/view_context'
|
|||
require 'draper/decorated_enumerable_proxy'
|
||||
require 'draper/rspec_integration' if defined?(RSpec) and RSpec.respond_to?(:configure)
|
||||
require 'draper/railtie' if defined?(Rails)
|
||||
|
||||
if defined?(Rails)
|
||||
module ActiveModel
|
||||
class Railtie < Rails::Railtie
|
||||
generators do |app|
|
||||
Rails::Generators.configure!(app.config.generators)
|
||||
require "generators/resource_override"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
28
lib/generators/decorator/decorator_generator.rb
Normal file
28
lib/generators/decorator/decorator_generator.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
module Rails
|
||||
module Generators
|
||||
class DecoratorGenerator < NamedBase
|
||||
source_root File.expand_path("../templates", __FILE__)
|
||||
check_class_collision :suffix => "Decorator"
|
||||
|
||||
class_option :parent, :type => :string, :desc => "The parent class for the generated decorator"
|
||||
|
||||
def create_decorator_file
|
||||
template 'decorator.rb', File.join('app/decorators', class_path, "#{file_name}_decorator.rb")
|
||||
end
|
||||
|
||||
hook_for :test_framework
|
||||
|
||||
private
|
||||
|
||||
def parent_class_name
|
||||
if options[:parent]
|
||||
options[:parent]
|
||||
elsif defined?(:ApplicationDecorator)
|
||||
"ApplicationDecorator"
|
||||
else
|
||||
"Draper::Base"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
class <%= singular_name.camelize %>Decorator < ApplicationDecorator
|
||||
<% module_namespacing do -%>
|
||||
class <%= class_name %>Decorator < ApplicationDecorator
|
||||
decorates :<%= singular_name %>
|
||||
|
||||
# Accessing Helpers
|
||||
|
@ -30,3 +31,4 @@ class <%= singular_name.camelize %>Decorator < ApplicationDecorator
|
|||
# :class => 'timestamp'
|
||||
# end
|
||||
end
|
||||
<% end -%>
|
|
@ -1,21 +0,0 @@
|
|||
module Draper
|
||||
module Generators
|
||||
class DecoratorGenerator < Rails::Generators::NamedBase
|
||||
source_root File.expand_path('../templates', __FILE__)
|
||||
|
||||
desc <<-DESC
|
||||
Description:
|
||||
Generate a decorator for the given model.
|
||||
Example: rails g draper:decorator Article
|
||||
generates: "app/decorators/article_decorator"
|
||||
"spec/decorators/article_decorator_spec"
|
||||
DESC
|
||||
|
||||
def create_decorator_file
|
||||
template 'decorator.rb', File.join('app/decorators', "#{singular_name}_decorator.rb")
|
||||
end
|
||||
|
||||
hook_for :test_framework
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
module Draper
|
||||
module Generators
|
||||
class InstallGenerator < Rails::Generators::Base
|
||||
source_root File.expand_path('../templates', __FILE__)
|
||||
|
||||
desc <<-DESC
|
||||
Description:
|
||||
Generate application and spec decorators in your application.
|
||||
DESC
|
||||
|
||||
def create_decorator_file
|
||||
template 'application_decorator.rb', File.join('app/decorators', 'application_decorator.rb')
|
||||
end
|
||||
|
||||
hook_for :test_framework, :as => :decorator do |test_framework|
|
||||
invoke test_framework, ['application']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
class ApplicationDecorator < Draper::Base
|
||||
# Lazy Helpers
|
||||
# PRO: Call Rails helpers without the h. proxy
|
||||
# ex: number_to_currency(model.price)
|
||||
# CON: Add a bazillion methods into your decorator's namespace
|
||||
# and probably sacrifice performance/memory
|
||||
#
|
||||
# Enable them by uncommenting this line:
|
||||
# lazy_helpers
|
||||
|
||||
# Shared Decorations
|
||||
# Consider defining shared methods common to all your models.
|
||||
#
|
||||
# Example: standardize the formatting of timestamps
|
||||
#
|
||||
# def formatted_timestamp(time)
|
||||
# h.content_tag :span, time.strftime("%a %m/%d/%y"),
|
||||
# :class => 'timestamp'
|
||||
# end
|
||||
#
|
||||
# def created_at
|
||||
# formatted_timestamp(model.created_at)
|
||||
# end
|
||||
#
|
||||
# def updated_at
|
||||
# formatted_timestamp(model.updated_at)
|
||||
# end
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ApplicationDecorator do
|
||||
end
|
|
@ -1,11 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class ApplicationDecoratorTest < ActiveSupport::TestCase
|
||||
def setup
|
||||
ApplicationController.new.set_current_view_context
|
||||
end
|
||||
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
12
lib/generators/resource_override.rb
Normal file
12
lib/generators/resource_override.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
require "rails/generators"
|
||||
require "rails/generators/rails/resource/resource_generator"
|
||||
|
||||
module Rails
|
||||
module Generators
|
||||
ResourceGenerator.class_eval do
|
||||
def add_decorator
|
||||
invoke "decorator"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe <%= singular_name.camelize %>Decorator do
|
||||
describe <%= class_name %>Decorator do
|
||||
end
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
require 'test_helper'
|
||||
|
||||
class <%= singular_name.camelize %>DecoratorTest < ActiveSupport::TestCase
|
||||
class <%= class_name %>DecoratorTest < ActiveSupport::TestCase
|
||||
def setup
|
||||
ApplicationController.new.set_current_view_context
|
||||
end
|
||||
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
require 'spec_helper'
|
||||
|
||||
# Generators are not automatically loaded by Rails
|
||||
require 'generators/draper/decorator_generator'
|
||||
require 'generators/decorator/decorator_generator'
|
||||
|
||||
describe Draper::Generators::DecoratorGenerator do
|
||||
describe Rails::Generators::DecoratorGenerator do
|
||||
# Tell the generator where to put its output (what it thinks of as Rails.root)
|
||||
destination File.expand_path("../../../../../tmp", __FILE__)
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
# Generators are not automatically loaded by Rails
|
||||
require 'generators/draper/install_generator'
|
||||
|
||||
describe Draper::Generators::InstallGenerator do
|
||||
# Tell the generator where to put its output (what it thinks of as Rails.root)
|
||||
destination File.expand_path("../../../../../tmp", __FILE__)
|
||||
|
||||
before { prepare_destination }
|
||||
|
||||
context 'using rspec' do
|
||||
before do
|
||||
run_generator ['', "-t=rspec"]
|
||||
end
|
||||
|
||||
shared_examples_for "ApplicationDecoratorGenerator" do
|
||||
describe 'app/decorators/application_decorator.rb' do
|
||||
subject { file('app/decorators/application_decorator.rb') }
|
||||
it { should exist }
|
||||
it { should contain "class ApplicationDecorator < Draper::Base" }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'spec/decorators/application_decorator_spec.rb' do
|
||||
subject { file('spec/decorators/application_decorator_spec.rb') }
|
||||
it { should exist }
|
||||
it { should contain "describe ApplicationDecorator do" }
|
||||
end
|
||||
end
|
||||
|
||||
context "using test_unit" do
|
||||
before { run_generator ["", "-t=test_unit"] }
|
||||
|
||||
it_should_behave_like "ApplicationDecoratorGenerator"
|
||||
|
||||
describe 'spec/decorators/application_decorator_spec.rb' do
|
||||
subject { file('spec/decorators/application_decorator_spec.rb') }
|
||||
it { should_not exist }
|
||||
end
|
||||
|
||||
describe 'spec/decorators/application_decorator_test.rb' do
|
||||
subject { file('test/decorators/application_decorator_test.rb') }
|
||||
it { should exist }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue