21

Click here to load reader

Padrino decorator

Embed Size (px)

DESCRIPTION

渋谷.rb[:20130918] での発表資料です

Citation preview

Page 1: Padrino decorator

デコレータのはなし

渋谷.rb[:20130918]Takeshi Yabe / @tyabe

Page 2: Padrino decorator
Page 3: Padrino decorator

app/views/posts/show.slim- if @post.image.present? = image_tag @post.image.url- else = image_tag ‘default.png’

こんなのがどんどんどんどん増えてくる

view

Page 4: Padrino decorator

models/post.rbclass Post < ActiveRecord::Base def image_url if self.image.present? self.image.url else ‘default.png’ end endend

app/views/posts/show.slim= image_tag @post.image_url

model?

Page 5: Padrino decorator

models/post.rbclass Post < ActiveRecord::Base def image_url if self.image.present? self.image.url else ‘default.png’ end endend

app/views/posts/show.slim= image_tag @post.image_url

View用のメソッドがModelに入っている

キモい

model?

Page 6: Padrino decorator

Helper?

app/helpers/posts_helper.rbStitchStitch::App.helpers do # ...end

・メソッド名の衝突を気にする必要がある・OOPっぽくない

Page 7: Padrino decorator

models/post.rbclass Post < ActiveRecord::Baseend

app/controllers/posts_controller.rbSampleProject::App.controllers :posts do get :show, with: :id do post = Post.find(params[:id]) @post_decorator = PostDecorator.new(post) render ‘posts/show’ endend

app/views/posts/show.slim- if @post_decorator.is_new_page? = image_tag @post_decorator.image

app/decorators/posts_decorator.rbclass PostDecorator attr_reader :post

def initialize(post) @post = post end

def image_url if self.image.present? self.image.url else ‘default.png’ end endend

表示用のロジックを Decorator に移す

Page 8: Padrino decorator

spec/app/decorators/post_decorator_spec.rbrequire 'spec_helper'

describe "PostDecorator" do it 'can construct a new instance' do post = create(:post) @post_decorator = PostDecorator.new(post, self) expect(@post_decorator.image_url).to eq ‘default.png’ endend

テストも書きやすくなる

Page 9: Padrino decorator

気軽に使いたいのでGeneratorを作った

Page 10: Padrino decorator
Page 11: Padrino decorator

$ padrino g decoratorUsage: padrino-gen decorator [name]

Options: -r, [--root=ROOT] # The root destination # Default: . -a, [--app=APP] # The application destination path # Default: /app -d, [--destroy] -n, [--namespace=NAMESPACE] # The name space of your padrino project

Description: padrino-gen decorator generates a new Padrino decorator

つかいかた

Page 12: Padrino decorator

$ tree .├── app

│ ├── app.rb

│ ├── controllers

│ ├── decorators

│ │   └── post_decorator.rb

│ ├── helpers

│ └── views

└── spec

└── app

└── decorators

└── post_decorator_spec.rb

Decorator用のファイルをつくります

Page 13: Padrino decorator

Rails

Page 14: Padrino decorator
Page 15: Padrino decorator
Page 16: Padrino decorator

Draper も実現することは基本的には同じですが、方式に違いがあります。ActiveDecorator はモデルオブジェクトにモジュールを extend するのに対し、Draper はモデルオブジェクトをラップするオブジェクトを作ってメソッドを移譲します。

Draper の方式ではメソッドを追加する前とした後でオブジェクトの identity が変化してしまうため、よくよく注意しないとハマります。

引用:Rubyist Magazine - Ruby on Rails: The Bad Partshttp://magazine.rubyist.net/?0041-RailsTheBadParts

Page 17: Padrino decorator
Page 18: Padrino decorator
Page 19: Padrino decorator
Page 20: Padrino decorator
Page 21: Padrino decorator

Let's talk about it.