SlideShare a Scribd company logo
Pragmatic Patterns
 of Ruby on Rails




Yasuko OHBA(     )
what I do


• developer of Rails applications
•
• Everyleaf Corporation
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
sponsor booth

• first time to be a sponsor
•   we serve candies

• you can play ‘Romantic Ruby’ !
my products


• home accounting web service
    http://www.kozuchi.net
•   http://github.com/everyleaf/kozuchi/
    tree
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
personal message
I started
programming when I
  was 14 years old
school for girls
I was alone
got the job
find similar people
however
‘enterprise’
only activities
inside the company
other things
 mount up
I was lost
want to write codes
that’s when..
Ruby was given
life becomes happier
Ruby for enterprises
the way to live
happily writing codes
And...
great communities
many friends
thank you !!
today’s presentation
coding patterns
     with
 Ruby on Rails
the target


• large & complicated applications
•   team
problems of large
        applications

• different coding styles
•   nasty parts made
becomes harder
to maintenance
keep your codes
      nice
what is the ‘nice code’?

• good design
• easy to understand
• easy to find something wrong
coding patterns work fine



• make and share coding patterns
• add some DSL (not too much)
efficient, of course
what I won’t say


• how to get the best performance
• ActiveRecord’s alternatives
ActiveRecord
frankly speaking,
I love ActiveRecord
because
OOP
still able to maintenance
when it gets complicated
pragmatic
the heart of RoR
many AR features in
 this presentation
examples
show permitted data
find starts from
 an AR object
find a note by id


           /note/3
def show
 @note = Note.find(params[:id])
end
find a note of the current user



                /note/3
@note = Note.find_by_id_and_user_id(
  params[:id], current_user.id)
raise ActiveRecord::RecordNotFound unless @note
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
/note/3

@note = Note.written_by(
 curret_user.id).find(params[:id])
hard to notice
the luck of condition!


@note = Note.find(params[:id])
@note = Note.find_by_id_and_user_id(
  params[:id], current_user.id)
@note = Note.written_by(
  current_user).find(params[:id])
so,
find starts from
 an AR object
starts from an object


def show
 @note = current_user.notes.find(
    params[:id])
end
use the association


def show
 @note = current_user.notes.find(
    params[:id])
end
association


class User < ActiveRecord::Base
  has_many :notes
end
easy to notice problems


@note = current_user.notes.find(
  params[:id])

@note = Note.find(params[:id])
easy to see
who can access
who can access


@note =
current_user.notes.find(
  params[:id])
filters to find
the starting AR object
with the previous
     pattern
most actions will
use the AR object
example;
CRUD of the specified
   group’s notes
•                      URL


• /groups/15/notes
• /groups/15/notes/3
• Note has group_id
class Note < ActiveRecord::Base
  belongs_to :group
end
class Group < ActiveRecord::Base
  has_many :notes
end
def index
 @group = Group.find(params[:group_id])
 @notes = @group.notes.paginate(:page =>
                           params[:page])
end
def show
 @group = Group.find(params[:group_id])
 @note = @group.notes.find(params[:id])
end
the duplicated line



@group = Group.find(params[:group_id])
write that line
  in a filter
what’s the filter?

• the separated logic which would be
  called around action



• declarative
find the group in a filter

class GroupNotesController < ApplicationController
 before_filter :find_group
  .......actions ......
 private
 def find_group
  @group = Group.find(params[:group_id])
 end
end
DRY

before_filter :find_group
def index
 @notes = @group.notes.paginate(:page =>
                           params[:page])
end
def show
 @note = @group.notes.find(params[:id])
end
easy to change
access control
example; change to allow
 access to members only



def find_group
 @group = current_user.groups.find(
                  params[:group_id]
end
other merits
secure
safe if it starts from @group


def index
 @notes = @group.notes.paginate(:page =>
                           params[:page])
end
def show
 @note = @group.notes.find(params[:id])
end
filter urges developers
    to use @group
and
readable
you can understand
the controller’s summary
  from name and filters
understand the summary
           quickly



class GroupNotesController <
                   ApplicationController
  before_filter :find_group
the points

•   a good controller name

•   readable filters
complicated
business logics
want to write
business logics
  in models
because
merits of writing
    business logics in models


• easy to test
• easy to reuse
• readable, easy to find the target codes
however
‘how’ matters a lot
a bad example

class MyModel < ActiveRecord::Base
  def do_create(params)
    ....
  def do_destroy(params)
    ...
end
why is it bad ?


• it breaks MVC
• hard to reuse
now
let’s move codes
from controller to model
       in good way
move the logic
branching on parameters
      from C to M
branching on parameters

def update
 @note.attributes = params[:note]
 @tags = params[:auto_tagging] == '1' ?
     generate_tags(@note) : []

 # do saving and tagging
 ...
end
often written in
   controller
to move to model
add an attribute for
branching to the model
the condition



params[:auto_tagging] == '1'
as an attribute of the model



class Note < ActiveRecord::Base
  attr_accessor :auto_tagging

end
change parameters structure


 { :note => {.....}, :auto_tagging => '1' }



 { :note => { ....., :auto_tagging => '1' }}
change the view for it


<%= check_box_tag :auto_tagging %>



<% form_for :note, ... do |f |%>
 <%= f.check_box :auto_tagging %>
<% end %>
now it’s in params[:note]



def update
 @note.attributes = params[:note]
 if params[:auto_tagging] == '1'
    generate_tags(@note)
 end
 .....
can branch in the model

class Note < ActiveRecord::Base
  ....
  if auto_tagging
      ...
  end
end
finished to move
    branching
move generate_tags next
move the logic
processing other models
     from C to M
the logic
processing other models

def update
    generate_tags(@note)
end
private
def generate_tags(note)
 tags = Tag.extract(note.body)
 note.tag_list = tags.join(',')
end
also often written in
     controller
put it into model’s callback

  class Note < ActiveRecord::Base
    before_save :generate_taggings

   private
   def generate_taggings
    return unless auto_tagging
    tags = Tag.extract(body)
    self.tag_list = tags.join(',')
   end
  end
what’s the model’s callback?



• methods called before/after save or
  destroy
Rails               Model                You
                          normal method call



                   save
        (validation)

        before_save
   do saving

            after_save
self-directive
   models
now we’ve done it !


• easy to test
• easy to reuse
• readable, easy to find the target codes
other patterns

•   multi levels for validation

•   design & coding policy for STI

•   use owner object’s attributes in association

•   how to make routes.rb a little readable
the last topic
how to find
coding patterns
in my case
try to choose
the most natural style
       for RoR
what is the most
   natural way
in Ruby on Rails?
1. OOP
express business
logics as models
always think who
should do that job
Note or User ?

@note = Note.find_by_id_and_user_id(
  params[:id], current_user.id)


@note = current_user.notes.find(
  params[:id])
you can’t always
decide it from tables
decide it
in objects world
2. follow the
principles of RoR
principles of RoR


•   DRY
•   CoC
•   RESTful
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
accept RESTful
in Ruby on Rails
how to design
 controllers ?
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
one controller for
a type of resources
what’s the resources?
you can find it in URL



/companies/everyleaf/notes/3
design of controllers
starts from
design of URLs
roughly speaking,
Model Class

    1
        1..*

 Resource
the point is...
one controller should
provide one resource
    type’s CRUD
might have been derailed

class BlogsController < ApplicationController
 def create_comment
 end
 def comments
 end
 def destroy_comment
 ...
one more
write codes in model’s
    standard flows
standard flows


•   find
•   new → save (create)
•   find → save (update)
•   find → destroy
inside of a flow
new       attribute =    before_
 build                   validation



before_      after_      validation
  save     validation



creation
           after_save
write codes in
appropriate place
where, what
 new          attribute =    before_
 build                      validation



before_         after_      validation
  save        validation



creation
              after_save
try to choose
the most natural style
       for RoR
don’t go too far
from the basic styles
because
it’s normal to
Rails programmers
easy to read
for everyone
for that purpose
use Ruby’s flexibility
summary
in developing
large & complicated
      application
it’s important
to keep codes nice
for that purpose
be aware of coding
     patterns,
 and share them
coding patterns
fitting Ruby on Rails
make source codes
 easy to read for
general developers
it means
easy to maintain
thank you !

More Related Content

What's hot (15)

PDF
Real-World Scala Design Patterns
NLJUG
 
PDF
Javanotes
John Cutajar
 
PPT
Ruby On Rails
Gautam Rege
 
ODP
What I Love About Ruby
Keith Bennett
 
PPTX
Scala’s implicits
Pablo Francisco Pérez Hidalgo
 
PPTX
OOP - Introduction to Inheritance
Mohammad Shaker
 
PPTX
Java script
Prarthan P
 
PPTX
Java script Session No 1
Saif Ullah Dar
 
PDF
Small Code - Ruby on Ales 2014
Mark Menard
 
PDF
Let's Do Some Upfront Design - WindyCityRails 2014
Mark Menard
 
PPTX
Coding standards for java
maheshm1206
 
PDF
Efficient Rails Test Driven Development (class 3) by Wolfram Arnold
Marakana Inc.
 
PDF
Small Code - RailsConf 2014
Mark Menard
 
PPT
introduction to javascript
Kumar
 
PDF
Write Small Things (Code)
Mark Menard
 
Real-World Scala Design Patterns
NLJUG
 
Javanotes
John Cutajar
 
Ruby On Rails
Gautam Rege
 
What I Love About Ruby
Keith Bennett
 
Scala’s implicits
Pablo Francisco Pérez Hidalgo
 
OOP - Introduction to Inheritance
Mohammad Shaker
 
Java script
Prarthan P
 
Java script Session No 1
Saif Ullah Dar
 
Small Code - Ruby on Ales 2014
Mark Menard
 
Let's Do Some Upfront Design - WindyCityRails 2014
Mark Menard
 
Coding standards for java
maheshm1206
 
Efficient Rails Test Driven Development (class 3) by Wolfram Arnold
Marakana Inc.
 
Small Code - RailsConf 2014
Mark Menard
 
introduction to javascript
Kumar
 
Write Small Things (Code)
Mark Menard
 

Viewers also liked (20)

PDF
Good Names in Right Places on Rails
Yasuko Ohba
 
PDF
TECH LAB PAAK 2015/06/24 Team Development
Yasuko Ohba
 
KEY
QCon2009 Tokyo - Ruby on Railsで変わるエンタープライズ開発の現場
Yasuko Ohba
 
PDF
Sendai ruby-02
Yasuko Ohba
 
PDF
Rubyによる開発プロジェクトをうまく回すには(2)
Yasuko Ohba
 
PDF
Rubyによる開発プロジェクトをうまく回すには(1)
Yasuko Ohba
 
PDF
名前のつけ方
Yasuko Ohba
 
PDF
テスト大嫌いっ娘のRSpec
Yasuko Ohba
 
PDF
Shimane2010
Yasuko Ohba
 
ODP
Balonmán touro
davidares1
 
PDF
Open il vol4
榎本 優樹
 
PDF
AWSome Day Berlin 18.6.2014
tecRacer
 
PDF
モバイルとソーシャルによる「学びの進化」を考える
webcampusschoo
 
PDF
最高の自分に進化する方法【コンサル起業実践講座】
伊藤 剛志
 
PPTX
driver
chaitanya shinde
 
PPT
J350 Social Media Intro
University of Oregon
 
PPT
Pirkanmaan toisen asteen tvt-suunnitelma ITK2014
Riikka Lehto (Vanninen)
 
PDF
Cognitive Biases: How the Clustering Illusion will impact your pitch
Siamac Rezaiezadeh
 
PPTX
Unit 2: NUTRITION
alfonsodios
 
PPSX
Bahadur shah (son of king prithivinarayan)
Ramesh Pant
 
Good Names in Right Places on Rails
Yasuko Ohba
 
TECH LAB PAAK 2015/06/24 Team Development
Yasuko Ohba
 
QCon2009 Tokyo - Ruby on Railsで変わるエンタープライズ開発の現場
Yasuko Ohba
 
Sendai ruby-02
Yasuko Ohba
 
Rubyによる開発プロジェクトをうまく回すには(2)
Yasuko Ohba
 
Rubyによる開発プロジェクトをうまく回すには(1)
Yasuko Ohba
 
名前のつけ方
Yasuko Ohba
 
テスト大嫌いっ娘のRSpec
Yasuko Ohba
 
Shimane2010
Yasuko Ohba
 
Balonmán touro
davidares1
 
Open il vol4
榎本 優樹
 
AWSome Day Berlin 18.6.2014
tecRacer
 
モバイルとソーシャルによる「学びの進化」を考える
webcampusschoo
 
最高の自分に進化する方法【コンサル起業実践講座】
伊藤 剛志
 
J350 Social Media Intro
University of Oregon
 
Pirkanmaan toisen asteen tvt-suunnitelma ITK2014
Riikka Lehto (Vanninen)
 
Cognitive Biases: How the Clustering Illusion will impact your pitch
Siamac Rezaiezadeh
 
Unit 2: NUTRITION
alfonsodios
 
Bahadur shah (son of king prithivinarayan)
Ramesh Pant
 
Ad

Similar to Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009 (20)

PDF
Rails antipattern-public
Chul Ju Hong
 
PDF
Rails antipatterns
Chul Ju Hong
 
PDF
HES2011 - joernchen - Ruby on Rails from a Code Auditor Perspective
Hackito Ergo Sum
 
PPTX
Random Ruby Tips - Ruby Meetup 27 Jun 2018
Kenneth Teh
 
PDF
Writing Readable Code
eddiehaber
 
PDF
Rails Tips and Best Practices
David Keener
 
PDF
Rspec and Capybara Intro Tutorial at RailsConf 2013
Brian Sam-Bodden
 
PDF
RoR 101: Session 2
Rory Gianni
 
PDF
2011-02-03 LA RubyConf Rails3 TDD Workshop
Wolfram Arnold
 
KEY
Código Saudável => Programador Feliz - Rs on Rails 2010
Plataformatec
 
PPTX
Intro to Rails 4
Kartik Sahoo
 
PPT
Jasig rubyon rails
_zaMmer_
 
PPT
Jasig rubyon rails
_zaMmer_
 
PPT
Intro to Rails ActiveRecord
Mark Menard
 
PPT
Intro to Ruby on Rails
Mark Menard
 
PDF
Web Development with Python and Django
Michael Pirnat
 
PDF
Ruby On Rails Introduction
Thomas Fuchs
 
PDF
Ruby On Rails
Balint Erdi
 
PPTX
Coding conventions
systemcrashed
 
KEY
Namespace less engine
shaokun
 
Rails antipattern-public
Chul Ju Hong
 
Rails antipatterns
Chul Ju Hong
 
HES2011 - joernchen - Ruby on Rails from a Code Auditor Perspective
Hackito Ergo Sum
 
Random Ruby Tips - Ruby Meetup 27 Jun 2018
Kenneth Teh
 
Writing Readable Code
eddiehaber
 
Rails Tips and Best Practices
David Keener
 
Rspec and Capybara Intro Tutorial at RailsConf 2013
Brian Sam-Bodden
 
RoR 101: Session 2
Rory Gianni
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
Wolfram Arnold
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Plataformatec
 
Intro to Rails 4
Kartik Sahoo
 
Jasig rubyon rails
_zaMmer_
 
Jasig rubyon rails
_zaMmer_
 
Intro to Rails ActiveRecord
Mark Menard
 
Intro to Ruby on Rails
Mark Menard
 
Web Development with Python and Django
Michael Pirnat
 
Ruby On Rails Introduction
Thomas Fuchs
 
Ruby On Rails
Balint Erdi
 
Coding conventions
systemcrashed
 
Namespace less engine
shaokun
 
Ad

More from Yasuko Ohba (15)

PDF
女性IT技術者と働き方 情報処理学会77
Yasuko Ohba
 
PDF
Girl, Geek and Company - Tokyo Girl Geek Dinners #5 2013/7/5
Yasuko Ohba
 
PDF
世界を描く Drawing the world
Yasuko Ohba
 
PDF
ごきげんRails
Yasuko Ohba
 
PDF
Smell in Rails Apps (in Sapporo RubyKaigi03)
Yasuko Ohba
 
PDF
The Basis of Making DSL with Ruby
Yasuko Ohba
 
PDF
Sub Resources Rails Plug-in
Yasuko Ohba
 
PDF
More Pragmatic Patterns of Ruby on Rails at Kansai Ruby Kaigi #02
Yasuko Ohba
 
PDF
Raspbilly
Yasuko Ohba
 
PDF
Shimane2008
Yasuko Ohba
 
PDF
Ruby on Rails 入門
Yasuko Ohba
 
PDF
image_upload Plugin 2007/12/7
Yasuko Ohba
 
PDF
Ruby on Rails ステップアップ講座 - 大場寧子
Yasuko Ohba
 
PDF
Ruby on Rails 中級者を目指して - 大場寧子
Yasuko Ohba
 
PDF
Bookscope 2007 09 07
Yasuko Ohba
 
女性IT技術者と働き方 情報処理学会77
Yasuko Ohba
 
Girl, Geek and Company - Tokyo Girl Geek Dinners #5 2013/7/5
Yasuko Ohba
 
世界を描く Drawing the world
Yasuko Ohba
 
ごきげんRails
Yasuko Ohba
 
Smell in Rails Apps (in Sapporo RubyKaigi03)
Yasuko Ohba
 
The Basis of Making DSL with Ruby
Yasuko Ohba
 
Sub Resources Rails Plug-in
Yasuko Ohba
 
More Pragmatic Patterns of Ruby on Rails at Kansai Ruby Kaigi #02
Yasuko Ohba
 
Raspbilly
Yasuko Ohba
 
Shimane2008
Yasuko Ohba
 
Ruby on Rails 入門
Yasuko Ohba
 
image_upload Plugin 2007/12/7
Yasuko Ohba
 
Ruby on Rails ステップアップ講座 - 大場寧子
Yasuko Ohba
 
Ruby on Rails 中級者を目指して - 大場寧子
Yasuko Ohba
 
Bookscope 2007 09 07
Yasuko Ohba
 

Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009