fat models aren't enough - railsconf

Upload: mirosa-mirosb

Post on 07-Apr-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    1/139

    Fat ModelsArent Enough

    Jeff Casimir / @j3

    learn by doing

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    2/139

    Best Practices

    2

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    3/139

    Refactoring by Hamlet DArcy

    3

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    4/139

    Refactoring by Hamlet DArcy

    3

    Don't touch anything that doesn't

    have[good test]coverage.

    Otherwise, you're not refactoring;you're just changingshit.

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    5/139

    4

    Question, Object, & Suggest

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    6/139

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    7/139

    Skinny Controllers,Fat Models

    Jamis Buck, October 2006

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    8/139

    6

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    9/139

    When first getting

    started with Rails,it is tempting to

    shove lots of

    6

    logic in the view.

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    10/139

    7

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    11/139

    A better way is to

    move as much of thelogic as possible

    7

    into the controller.

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    12/139

    8

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    13/139

    If we push that code

    into the model, we...

    8

    slim down

    the controller

    document the

    operation by namingthe method

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    14/139

    9The Rails Stack

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    15/139

    9The Rails Stack

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    16/139

    BeautifulViews are HTML

    10

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    17/139

    BeautifulActions are 8 simple lines

    11

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    18/139

    Beautiful Models are Organized

    12

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    19/139

    Fat Models Arent Enough

    13

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    20/139

    Why

    Bother?

    14

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    21/139

    Ideas for discussion

    15

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    22/139

    Ideas for discussion

    15

    Presenter Pattern

    Better Rails throughBetterRuby

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    23/139

    The Presenter Pattern

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    24/139

    Presenter Pattern, Formally

    17

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    25/139

    Presenter Pattern, Formally

    17

    Adaptation of the

    Decorator Pattern

    Wrapper that adds

    non-mutator

    methods

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    26/139

    Presenter Pattern, As I See It

    18

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    27/139

    Presenter Pattern, As I See It

    18

    Object-based

    shepherd of

    presentation

    Understands themixing of one or

    more objects

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    28/139

    19In Need of a Presenter

    /app/controllers/reports_controller.rb

    /app/views/reports/show.html.haml

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    29/139

    201a. Build Presenter

    /app/presenters/student_report.rb

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    30/139

    201a. Build Presenter

    /app/presenters/student_report.rb

    attr_reader:student, :term, :report_type

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    31/139

    201a. Build Presenter

    /app/presenters/student_report.rb

    attr_reader:student, :term, :report_type

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    32/139

    201a. Build Presenter

    /app/presenters/student_report.rb

    attr_reader:student, :term, :report_type

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    33/139

    201a. Build Presenter

    /app/presenters/student_report.rb

    attr_reader:student, :term, :report_type

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    34/139

    201a. Build Presenter

    /app/presenters/student_report.rb

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    35/139

    211b. Use the Presenter

    /app/controllers/reports_controller.rb

    /app/views/reports/show.html.haml

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    36/139

    211b. Use the Presenter

    /app/controllers/reports_controller.rb

    /app/views/reports/show.html.haml

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    37/139

    211b. Use the Presenter

    /app/controllers/reports_controller.rb

    /app/views/reports/show.html.haml

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    38/139

    222b. Presenter as Engine

    /app/presenters/student_report.rb

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    39/139

    222b. Presenter as Engine

    /app/presenters/student_report.rb

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    40/139

    222b. Presenter as Engine

    /app/presenters/student_report.rb

    Tuesday, May 17, 2011

    b D f E i

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    41/139

    232b. Defer to Engine

    /app/views/reports/show.html.haml

    - @report.courses.each do |course|- course_report [email protected]_data_for_course(course)

    = render:partial => "course_report", :locals =>{:course_report => course_report}

    Tuesday, May 17, 2011

    2b D f E i

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    42/139

    232b. Defer to Engine

    /app/views/reports/show.html.haml

    - @report.courses.each do |course|- course_report [email protected]_data_for_course(course)

    = render:partial => "course_report", :locals =>{:course_report => course_report}

    = render:partial => 'course_report',:collection => @report.course_reports

    Tuesday, May 17, 2011

    2b D f E i

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    43/139

    232b. Defer to Engine

    /app/views/reports/show.html.haml

    = render:partial => 'course_report',:collection => @report.course_reports

    Tuesday, May 17, 2011

    2b D f t E i

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    44/139

    232b. Defer to Engine

    /app/views/reports/show.html.haml

    = [email protected]_reports

    Asks each element for its ClassName

    Renders the partial with that name andsets the local variable

    Tuesday, May 17, 2011

    3 C t i E i

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    45/139

    243a. Compute in Engine

    /app/presenters/student_report.rb

    Tuesday, May 17, 2011

    3 C t i E i

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    46/139

    243a. Compute in Engine

    /app/presenters/student_report.rb

    defcourse_reportscourses.collect do |c|

    end end

    end

    @student.report_data_for_course(c)

    Tuesday, May 17, 2011

    3 C t i E i

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    47/139

    243a. Compute in Engine

    /app/presenters/student_report.rb

    defcourse_reportscourses.collect do |c|

    end end

    end

    @student.report_data_for_course(c)

    Tuesday, May 17, 2011

    3 C t i E i

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    48/139

    243a. Compute in Engine

    /app/presenters/student_report.rb

    defcourse_reportscourses.collect do |c|

    end end

    end

    defreport_data_for_course(course) # Compute the report data end

    @student.report_data_for_course(c)

    Tuesday, May 17, 2011

    3 C t i E i

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    49/139

    243a. Compute in Engine

    /app/presenters/student_report.rb

    defcourse_reportscourses.collect do |c|

    end end

    end

    defreport_data_for_course(course) # Compute the report data end

    report_data_for_course(c)

    Tuesday, May 17, 2011

    4 C i l D t

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    50/139

    254. Canonical Data

    /app/views/reports/show.html.haml

    /app/presenters/student_report.rb

    @report.name

    "#{@report.last_name}, #{@report.first_name}""#{@report.report_title} for #{@report.start_date} to#{@report.end_date}"

    Tuesday, May 17, 2011

    4 C i l D t

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    51/139

    254. Canonical Data

    /app/views/reports/show.html.haml

    /app/presenters/student_report.rb

    @report.name

    "#{@report.last_name}, #{@report.first_name}""#{@report.report_title} for #{@report.start_date} to#{@report.end_date}"

    defstudent_name[last_name, first_name].join(", ")

    end

    Tuesday, May 17, 2011

    4 C i l D t

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    52/139

    254. Canonical Data

    /app/views/reports/show.html.haml

    /app/presenters/student_report.rb

    @report.name

    "#{@report.report_title} for #{@report.start_date} to#{@report.end_date}"

    defstudent_name[last_name, first_name].join(", ")

    end

    @report.student_name

    Tuesday, May 17, 2011

    4 C i l D t

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    53/139

    deftitle "#{report_title} for #{start_date} to #{end_date}" end

    254. Canonical Data

    /app/views/reports/show.html.haml

    /app/presenters/student_report.rb

    @report.name

    "#{@report.report_title} for #{@report.start_date} to#{@report.end_date}"

    defstudent_name[last_name, first_name].join(", ")

    end

    @report.student_name

    Tuesday, May 17, 2011

    4 Canonical Data

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    54/139

    deftitle "#{report_title} for #{start_date} to #{end_date}" end

    254. Canonical Data

    /app/views/reports/show.html.haml

    /app/presenters/student_report.rb

    @report.name

    defstudent_name[last_name, first_name].join(", ")

    end

    @report.student_name

    @report.title

    Or maybe a decorator?

    Tuesday, May 17, 2011

    5 End State Review

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    55/139

    265. End State Review

    Tuesday, May 17, 2011

    5 End State Review

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    56/139

    265. End State Review

    /app/views/reports/show.html.haml

    Tuesday, May 17, 2011

    5 End State Review

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    57/139

    265. End State Review

    /app/controllers/reports_controller.rb

    /app/views/reports/show.html.haml

    Tuesday, May 17, 2011

    5 End State

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    58/139

    275. End State

    Tuesday, May 17, 2011

    5 End State

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    59/139

    275. End State

    /app/presenters/student_report.rb (rst half)

    Tuesday, May 17, 2011

    5 End State

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    60/139

    285. End State

    /app/presenters/student_report.rb (second half)

    Tuesday, May 17, 2011

    5 End State

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    61/139

    285. End State

    /app/presenters/student_report.rb (second half)

    Tuesday, May 17, 2011

    Afterthoughts

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    62/139

    29Afterthoughts

    Tuesday, May 17, 2011

    Afterthoughts

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    63/139

    29

    Did you just obliterate MVC?

    Afterthoughts

    Tuesday, May 17, 2011

    Afterthoughts

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    64/139

    29

    Did you just obliterate MVC?

    Why not just use helpers?

    Afterthoughts

    Tuesday, May 17, 2011

    Afterthoughts

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    65/139

    29

    Did you just obliterate MVC?

    Why not just use helpers?

    They suck

    Afterthoughts

    Tuesday, May 17, 2011

    Afterthoughts

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    66/139

    29

    Did you just obliterate MVC?

    Why not just use helpers?

    They suck

    Objects are not scary

    Afterthoughts

    Tuesday, May 17, 2011

    Afterthoughts

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    67/139

    29

    Did you just obliterate MVC?

    Why not just use helpers?

    They suck

    Objects are not scary

    Using Rails helpers is ok!

    Afterthoughts

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    68/139

    Better Rails throughBetter Ruby

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    69/139

    31

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    70/139

    A significant percentage of

    Rails programmers are not

    Ruby programmers.

    (my theory)

    31

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    71/139

    Dont RepeatYourself (DRY)

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    72/139

    Dont copy and paste code.

    Dont RepeatYourself (DRY)

    Dave Thomas & Andy Hunt

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    73/139

    Every piece of knowledge must have a single,

    unambiguous, authoritative representation within a system.

    Dont RepeatYourself (DRY)

    Dave Thomas & Andy Hunt

    Tuesday, May 17, 2011

    33Real-World DRY: Sort

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    74/139

    33Real-World DRY: Sort

    Tuesday, May 17, 2011

    33Real-World DRY: Sort

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    75/139

    33Real World DRY: Sort

    Typical Param-Handling Action

    Tuesday, May 17, 2011

    33Real-World DRY: Sort

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    76/139

    33Real World DRY: Sort

    Typical Param-Handling Action

    Tuesday, May 17, 2011

    34Real-World DRY: Sort

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    77/139

    34Real World DRY: Sort

    Tuesday, May 17, 2011

    34Real-World DRY: Sort

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    78/139

    34Real World DRY: Sort

    Simple DRY Improvement

    Tuesday, May 17, 2011

    35Real-World DRY: Sort

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    79/139

    35Real World DRY: Sort

    Tuesday, May 17, 2011

    35Real-World DRY: Sort

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    80/139

    35Real World DRY: Sort

    class StudentsController < ApplicationControllerdefindex

    @students=Student.all_by(params[:sort_by]) endend

    Tuesday, May 17, 2011

    35Real-World DRY: Sort

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    81/139

    35Real World DRY: Sort

    Real DRY Progress

    class StudentsController < ApplicationControllerdefindex

    @students=Student.all_by(params[:sort_by]) endend

    class Student < ActiveRecord::Base defself.all_by(param) case param when"last_name"then order(:last_name) when"first_name"then order(:first_name) else order(:id) end

    endend Thinking about scope?

    Give me a minute.

    Tuesday, May 17, 2011

    36Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    82/139

    36Real World DRY: Setters

    Tuesday, May 17, 2011

    36Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    83/139

    36Real World DRY: Setters

    Action Setting Attributes

    Tuesday, May 17, 2011

    37Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    84/139

    37Real World DRY: Setters

    Tuesday, May 17, 2011

    37Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    85/139

    37Real World DRY: Setters

    class StudentsController < ApplicationControllerdefcreate

    @student=Student.new(params, current_user) # redirects, etcend

    end

    Tuesday, May 17, 2011

    37Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    86/139

    37Real World DRY: Setters

    Trying to Encapsulate Creation

    class StudentsController < ApplicationControllerdefcreate

    @student=Student.new(params, current_user) # redirects, etcend

    end

    class Student < ActiveRecord::Base definitialize(params, creator) self.created_by = creator self.lunch_id =LunchTracker.new self.lunch_balance =LunchTracker::STARTING_BALANCE super

    endend

    Tuesday, May 17, 2011

    38Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    87/139

    38Real World DRY: Setters

    Tuesday, May 17, 2011

    38Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    88/139

    38Real World DRY: Setters

    Build Through the Relationship

    class StudentsController < ApplicationControllerdefcreate

    @student= current_user.students.new(params) # redirects, etcend

    end

    Tuesday, May 17, 2011

    38Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    89/139

    38Real World DRY: Setters

    Build Through the Relationship

    class StudentsController < ApplicationControllerdefcreate

    @student= current_user.students.new(params) # redirects, etcend

    end

    class Student < ActiveRecord::Base definitialize(params = nil) self.lunch_id =LunchTracker.new self.lunch_balance =LunchTracker::STARTING_BALANCE super endend

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    90/139

    Single Responsibility Principle

    39

    Tuesday, May 17, 2011

    E bj t h ld

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    91/139

    Single Responsibility Principle

    39

    Every object should

    have a single

    responsibility, and

    that responsibility

    should be entirelyencapsulated by

    the class.

    Tuesday, May 17, 2011

    40Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    92/139

    40Real World DRY: Setters

    Tuesday, May 17, 2011

    40Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    93/139

    40ea o d Se e s

    SRP Cleanup

    class Student < ActiveRecord::Base definitialize(params = nil) self.lunch_id =LunchTracker.new

    super end

    end

    self.lunch_balance =LunchTracker::STARTING_BALANCE

    Tuesday, May 17, 2011

    40Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    94/139

    40

    SRP Cleanup

    class Student < ActiveRecord::Base definitialize(params = nil) self.lunch_id =LunchTracker.new

    super end

    end

    self.lunch_balance =LunchTracker::STARTING_BALANCE

    Tuesday, May 17, 2011

    40Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    95/139

    0

    SRP Cleanup

    class Student < ActiveRecord::Base definitialize(params = nil) self.lunch_id =LunchTracker.new

    super end

    end

    self.lunch_balance =LunchTracker::STARTING_BALANCE

    Tuesday, May 17, 2011

    40Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    96/139

    SRP Cleanup

    class Student < ActiveRecord::Base definitialize(params = nil) self.lunch_id =LunchTracker.new

    super end

    end

    Tuesday, May 17, 2011

    41Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    97/139

    Tuesday, May 17, 2011

    41Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    98/139

    More Repetition

    class Student < ActiveRecord::Base definitialize(params=nil)

    super endend

    self.lunch_id =LunchTracker.new

    Tuesday, May 17, 2011

    41Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    99/139

    More Repetition

    class Student < ActiveRecord::Base

    definitialize(params=nil)

    super

    endend

    has_one:lunch, :class_name => 'LunchTracker'

    self.lunch_id =LunchTracker.new

    Tuesday, May 17, 2011

    41Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    100/139

    More Repetition

    class Student < ActiveRecord::Base

    definitialize(params=nil)

    super

    endend

    has_one:lunch, :class_name => 'LunchTracker'

    self.lunch_id =LunchTracker.new

    Tuesday, May 17, 2011

    41Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    101/139

    More Repetition

    class Student < ActiveRecord::Base

    definitialize(params=nil)

    super

    endend

    has_one:lunch, :class_name => 'LunchTracker'

    self.build_lunch

    Tuesday, May 17, 2011

    42Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    102/139

    Tuesday, May 17, 2011

    42Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    103/139

    Start / End Review

    class StudentsController < ApplicationControllerdefcreate

    @student=Student.new(params[:student]) @student.created_by = current_user @student.lunch_id =LunchTracker.new @student.lunch_balance =0

    # redirects, etcend

    end

    Tuesday, May 17, 2011

    42Real-World DRY: Setters

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    104/139

    class StudentsController < ApplicationControllerdefcreate

    @student= current_user.students.new(params) # redirects, etcend

    end

    class Student < ActiveRecord::Base has_one:lunch, :class_name => 'LunchTracker'definitialize(params = nil)

    self.build_lunch super endend

    Start / End Review

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    105/139

    Signs of SRP Violations 43

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    106/139

    Signs of SRP Violations

    Methods that do too much

    Symptom:Your method is longer than 8 linesSolution: refactor with extract method

    43

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    107/139

    Signs of SRP Violations

    Methods that do too much

    Symptom:Your method is longer than 8 linesSolution: refactor with extract method

    Methods located in the wrong object

    Symptom: reaching too deeply into child objects / Law of Demeter

    Solution: refactor with move method

    43

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    108/139

    Signs of SRP Violations

    Methods that do too much

    Symptom:Your method is longer than 8 linesSolution: refactor with extract method

    Methods located in the wrong object

    Symptom: reaching too deeply into child objects / Law of Demeter

    Solution: refactor with move method

    Magic Numbers, copy text, and configuration data

    Solution: introduce constants or a config object

    43

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    109/139

    Scopes are Dead

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    110/139

    Why We Loved Scopes 45

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    111/139

    Simple Scope in Rails 3 46

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    112/139

    Simple Scope in Rails 3 46

    Quick and Easy

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    113/139

    A Gotcha Scenario 47

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    114/139

    A Gotcha Scenario 47

    Frank creates a migration adding the

    inactive field to Student

    Frank writes a scope like this:scope :active, where(:inactive => false)

    Frank checks in his code, woohoo!

    Lucy checks out Franks code

    Lucy runs rake db:migrate

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    115/139

    A Gotcha Scenario 47

    Frank creates a migration adding the

    inactive field to Student

    Frank writes a scope like this:scope :active, where(:inactive => false)

    Frank checks in his code, woohoo!

    Lucy checks out Franks code

    Lucy runs rake db:migrate

    fixedin

    3.0.2+

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    116/139

    Scope with Parameters 48

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    117/139

    Scope with Parameters 48

    Lambda ZOMG!

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    118/139

    AREL and Lazy Evaluation 49

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    119/139

    Scopes & Lambdas 50

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    120/139

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    121/139

    Scopes & Lambdas 50

    Tuesday, May 17, 2011

    We dont need scopes,

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    122/139

    We don t need scopes,

    just write good Ruby. 51

    Tuesday, May 17, 2011

    We dont need scopes,

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    123/139

    We don t need scopes,

    just write good Ruby. 51

    Class Methods > Scopes

    Tuesday, May 17, 2011

    52Wrap Up

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    124/139

    Tuesday, May 17, 2011

    52Wrap Up

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    125/139

    Use presenters as an abstraction layer between views

    and models

    DRY isnt about copy & paste, its about knowledge

    Forget scopes, you dont need them!

    Embrace Ruby

    Jeff Casimir

    @j3

    learn by doing

    Tuesday, May 17, 2011

    53

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    126/139

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    127/139

    Writing Better Instructions

    54

    Tuesday, May 17, 2011

    Every instruction

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    128/139

    Writing Better Instructions

    54

    y

    added is technical

    debt accumulated.

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    129/139

    Less code is less debt 55

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    130/139

    Less code is less debt

    self is rarely necessary

    55

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    131/139

    Less code is less debt

    self is rarely necessary

    return is rarely necessary

    55

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    132/139

    Less code is less debt

    self is rarely necessary

    return is rarely necessary

    Master collection operations including:each, collect/map, select, detect, merge

    55

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    133/139

    Less code is less debt

    self is rarely necessary

    return is rarely necessary

    Master collection operations including:each, collect/map, select, detect, merge

    Take advantage of return values from all statements, evenif, case, while

    55

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    134/139

    Method Naming 56

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    135/139

    Method Naming

    Names matter

    Express meaning, imply the return type and quantity

    56

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    136/139

    Method Naming

    Names matter

    Express meaning, imply the return type and quantity

    Follow Ruby naming conventions

    Solutions: if it changes the data, end in !

    if it returns a boolean, end in ?

    56

    Tuesday, May 17, 2011

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    137/139

    Method Naming

    Names matter

    Express meaning, imply the return type and quantity

    Follow Ruby naming conventions

    Solutions: if it changes the data, end in !

    if it returns a boolean, end in ?

    Physically organize methods within a model...

    56

    Tuesday, May 17, 2011

    57Collecting Class Methods

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    138/139

    class Student class

  • 8/3/2019 Fat Models Aren't Enough - RailsConf

    139/139

    class Student class