An Introduction to Trailblazer Matthew Jording Consultant
@mjording / github.com/mjording March 13th
#trbrb
The Challenge: Managing Complexity
Complexity by Mark Skipper via Flickr CC BY 2.0
Common Symptoms • New features are hard to estimate • People are afraid to touch parts of the code • New developers take a long time to ramp up • Code is hard to unit test • CI build is brittle and takes forever • Big classes with many responsibilities • Hard to know where to put new logic • …
Every Application Faces It
Rails MVC
Best Practices • Too much logic in your view?
- Bryan Helmkamp, Brian Vanloo, James Golick, and many others
Best Practices • Too much logic in your view? – Put it in a view model instead t
- Bryan Helmkamp, Brian Vanloo, James Golick, and many others
Best Practices • Too much logic in your view? – Put it in a view model instead
• Too much logic in your controller?
- Bryan Helmkamp, Brian Vanloo, James Golick, and many others
Best Practices • Too much logic in your view? – Put it in a view model instead
• Too much logic in your controller? – Put it in a form object, a policy object, or a service object instead
- Bryan Helmkamp, Brian Vanloo, James Golick, and many others
Best Practices • Too much logic in your view? – Put it in a view model instead
• Too much logic in your controller? – Put it in a form object, a policy object, or a service object instead
• Too much logic in your model?
- Bryan Helmkamp, Brian Vanloo, James Golick, and many others
Best Practices • Too much logic in your view? – Put it in a view model instead
• Too much logic in your controller? – Put it in a form object, a policy object, or a service object instead
• Too much logic in your model? – Put it in a service object or a value object instead –t - Bryan Helmkamp, Brian Vanloo, James Golick, and many others
Encapsulate Related Logic • • • • • • •
View Model Form Object Service Object Policy Object Value Object Query Object …
• • • •
Benefits Small classes Easier to unit test Easier to understand Single responsibility
Great!
Great! But there are so many options which do I choose… and how do I know if I’m on the right track…
Great! But there are so many options which do I choose… and how do I know if I’m on the right track…
Wait, isn’t there a gem for that?
Trailblazer
An architectural layer for ruby-based web applications
Trailblazer
A set of Gems to help with implementing these patterns
Trailblazer
With clear conventions for where to put your logic
Trailblazer
https://leanpub.com/trailblazer
http://trailblazer.to/
And extensive documentation
Trailblazer
A set of Gems to help with implementing these patterns
Trailblazer
A set of Gems to help with implementing these patterns
Trailblazer
A set of Gems to help with implementing these patterns
An Example
• A User can only view and edit their own Accounts • New Accounts should belong to the User that created them • An Account must have a name
Rails MVC
Trailblazer
GET /accounts/1
Traditional Rails controllers/accounts_controller.r
GET /accounts/1
Trailblazer
controllers/accounts_controller.r
GET /accounts/1
Trailblazer
concepts/account/read.rb
GET /accounts/1
Trailblazer
concepts/account/policy.rb
GET /accounts/new
POST /accounts
Traditional Rails controllers/accounts_controller.r
GET /accounts/new
POST /accounts
Trailblazer
controllers/accounts_controller.r
GET /accounts/new
POST /accounts
Trailblazer
concepts/account/create.rb
GET /accounts/new
POST /accounts
Trailblazer spec/concepts/account/create_spec
Trailblazer
concepts/account/policy.rb
GET /accounts/new
POST /accounts
Trailblazer
concepts/account/contract.rb
GET /accounts/new
POST /accounts
Trailblazer
concepts/account/contract.rb
GET /accounts/new
POST /accounts
Traditional Rails
models/account.rb
GET /accounts/new
POST /accounts
Trailblazer
models/account.rb
GET /accounts/new
POST /accounts
Traditional Rails
views/accounts/show.html.erb
GET /accounts/new
POST /accounts
Trailblazer
views/accounts/show.html.erb
New Requirements As a user, I should be able to: • View all transactions for an account • See my current and available balance • See a visual indicator for pending transactions • See the category for each transaction • See a flag for uncategorized transactions • …
New Requirements
Account Summary Page
Account Summary Page
Traditional Rails
views/accounts/show.html.erb
Account Summary Page
views/accounts/show.html.erb
Trailblazer
Account Summary Page
Trailblazer
concepts/account/cell.rb
Account Summary Page
Trailblazer
concepts/account/views/show.er
Account Summary Page
Trailblazer
concepts/account/row_cell.rb
Account Summary Page
concepts/account/views/row_cell.erb
Trailblazer
Account Summary Page
The Cool Stuff • • • • • • • •
Operations orchestrate complex business logic Policies cleanly handle authorization Cells manage complexity in the view layer Reform enables editing multiple models at once Representable and ROAR for APIs Testability Great documentation with clear patterns Supportive community
The Not-so-Cool Stuff • The learning curve • ReForm objects with nested properties can be finicky • Partial use of Trailblazer can make app harder to understand • Sharing model namespace can sometimes cause weird TypeErrors (Account::Create shares Account < ActiveRecord::Base)
When and where to use Trailblazer? • New projects that will need to scale • Existing large projects that use patterns inconsistently • Existing projects that need only part of it
Thank you • Nick Sutterer (@apotonick) • The Trailblazer community
Trailblazer Resources • http://trailblazer.to • https://leanpub.com/trailblazer • https://gitter.im/trailblazer/chat
Articles Referenced • http://blog.codeclimate.com/blog/ 2012/10/17/7-ways-to-decompose-fatactiverecord-models/ • https://www.toptal.com/ruby-on-rails/ top-10-mistakes-that-rails-programmersmake • http://jamesgolick.com/2010/3/14/crazyheretical-and-awesome-the-way-i-writerails-apps.html • http://objectsonrails.com/
Questions?