Iteration Podcast
A System for Growth
A weekly podcast about programming, development, and design through the lens of amazing books, chapter-by-chapter.
A System for Growth
Dealing with complicated models
-
John: How / Why do they grow? Needs change:
-
John: All the different use cases for a user
John:
"When you need to implement password recovery, and do not have a clear, single place to put the logic, it will still find its way into your code. It will spread itself across existing classes, usually making those classes harder to read and use.”
Example problem: Want to send a welcome email when a user is created via a public form but not when an admin creates a user via a backend interface
- Fat models == missing classes
- don't actively look for an AR class, look for new classes to contain new logic
A home for interaction specific code
Core models should only have the absolute minimum to exist:
- set of validations to enforce data integrity
- definitions for associations (belongs_to, has_many)
- universally useful convenience methods to find or manipulate records (scopes)
Core models should NOT have these things: (these things belong in multiple, interaction-specific form models)
-
virtual attributes that don't map 1:1 with db
-
callbacks to fire for a particular screen or use case (i.e. form signup)
-
we want the perks of AR models with AR. solution: inheritance
class User::AsSignUp < User
validates :password, presence: true, confirmation: true
after_create :send_welcome_emailprivate def send_welcome_email; end
end
-
John: Note the "AsSignup" pattern - "AsFacebookAuth"
Extracting service objects (lol)
- probably a good indicator of a service object is when you find yourself using class methods. i.e.
def self.something
- John: Didn’t we just move code around? - "what used to be a monolithic blob of intertwined logic is now separated into multiple, loosely coupled components.” Better maintainability, testing, and reuse.
Organizing large codebases with namespaces
class Invoice < ActiveRecord::Base
has_many :items
end
class Item < ActiveRecord::Base
belongs_to:invoice
end
Why not just:
class Invoice::Item < ActiveRecord::Base
belongs_to:invoice
end
and move the file to: app/models/invoice/item.rb
- core domain at a glance
- John: Pros- Namespaces have an inherent hierarchy - Encourages more objects, clear path for them.
Taming Stylesheets
The recommendations are a lot like BEM - A front-end development methodology - learn more at: http://getbem.com/
- John - Recommend a Readme.md for front-end specific code, or having front end specific guides in the readme.
- John - Have a process, and document your process. Have a system.
- John - Contractor (Frank Hock) - Recommended a very specific folder structure:
Abstracts (Sizing, Boarders, Spacing)Base (Grid, Colors, images, Typography)Components (Buttons, Cards, Alerts)Page Specific CSS
Picks:
- John: Elasticsearch with Bonsai - Such a great experience and amazing performance so far.
- JP: https://github.com/kelseyhightower/nocode