Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Sanity on Rails — How to write maintainable Rai...

Sanity on Rails — How to write maintainable Rails applications in 2017

Rails is not your application! Don’t overcomplicate your development life by trying to make everything fit within its MVC structure. A framework provides tools and abstractions, use them to build your business logic, don’t force your business logic to fit into them.

Michael Kohl

August 12, 2017

Transcript

28 slides
  1. • Michael Kohl (@citizen428) • CTO @ Lockstep Labs •

    Based in Bangkok, Thailand • Ruby developer since ~2004 • Former mentor at RubyLearning Deccan RubyConf 2017 locksteplabs.com Yours truly
  2. Deccan RubyConf 2017 locksteplabs.com The problem • Recurring problems •

    Dependencies • Framework entanglement • Implicit code • Good news: easily avoidable
  3. Deccan RubyConf 2017 locksteplabs.com Dependencies • Bootstrap the app faster

    • Prevent “not invented here syndrome” • Get peer reviewed • Easily get outdated • Memory footprint & startup times • Have more dependencies
  4. Deccan RubyConf 2017 locksteplabs.com Dependencies • Be selective about dependencies

    • Look for actively maintained gems • Use gems for common tasks • Prefer developers with vested interest
  5. "A basic conceptional structure (as of ideas)" – Merriam Webster

    "A basic structure underlying a system, concept, or text." – Oxford English dictionary Deccan RubyConf 2017 locksteplabs.com Frameworks
  6. Deccan RubyConf 2017 locksteplabs.com Frameworks - Controllers • Abstracting HTTP

    communication • Authentication • Authorization • Sessions / cookies • Param validation / transformation • Redirection / rendering
  7. Deccan RubyConf 2017 locksteplabs.com Frameworks - Controllers # Actions resources

    :actions, only: [:index] namespace :actions do resource :enqueue_cvs, only: [:create] resource :import_cvs, only: [:create] resource :generate_suggestions, only: [:create] resource :logs, only: [:destroy] end # Users resources :users, except: [:new, :edit, :show] namespace :users do resources :filters, only: [:create] resources :passwords, only: [:create, :edit, :update] end
  8. Deccan RubyConf 2017 locksteplabs.com Frameworks - Models • Wrapper around

    datastore • ActiveRecord configuration • Associations • Validations • Finders / scopes • Simple accessors / mutation methods
  9. Deccan RubyConf 2017 locksteplabs.com Frameworks - Models • Extract POROs

    • Various extraction patterns • Service objects • Form objects • Query objects • many more • Use namespacing
  10. Deccan RubyConf 2017 locksteplabs.com Frameworks - Models ! tree app/services/cv

    app/services/cv "## file_mover.rb "## importer.rb "## parser.rb "## repository.rb "## suggestion_handler.rb $## viewer.rb
  11. Deccan RubyConf 2017 locksteplabs.com Frameworks - Models require_dependency 'cv' class

    Cv # Class for importing CV files into ElasticSearch in a standardized way. class Importer attr_accessor :file_name, :content, :md5sum, :file_type, :attributes, :parse def self.import(file_name, content, attr = {}) new(file_name, content, attr).import end def initialize(file_name, content, attr = {}) self.file_name = File.basename(file_name) … parse_attributes(attr) end def import add_to_es extract_plaintext parse_cv if parse end
  12. Deccan RubyConf 2017 locksteplabs.com Frameworks - Models class AbandonedTrialQuery def

    initialize(relation = Account.scoped) @relation = relation end def find_each(&block) @relation. where(plan: nil, invites_count: 0). find_each(&block) end end Credit: Code Climate
  13. Deccan RubyConf 2017 locksteplabs.com Frameworks - Views • Response generation

    • Should be mostly logic free • Rails conflates view model & template • Helpers become dumping grounds
  14. Deccan RubyConf 2017 locksteplabs.com Frameworks - Views class UserView <

    ApplicationView include ActionView::Helpers::TagHelper forward :first_name, :last_name def formatted_full_name content_tag :strong, "#{first_name} #{last_name}" end end
  15. Deccan RubyConf 2017 locksteplabs.com Implicit code • “Convention over configuration”

    • Magic: • AR configuration • Instance variables in views • Implicit code: • AR callbacks • before_action/after_action
  16. Deccan RubyConf 2017 locksteplabs.com Implicit code • Hard for newcomers

    to understand • Hard to follow code flow • Easy, not simple • Doesn’t apply in all cases
  17. Deccan RubyConf 2017 locksteplabs.com Implicit code • Be more explicit!

    • Reading is more important than writing! • POROs to encapsulate processes • Don’t try to be too clever!
  18. • Be selective when adding gems • Build business logic

    on top of what Rails provides, don’t mix it with framework code • Explicit is often better than implicit • There are no silver bullets, all software development involves tradeoffs. Deccan RubyConf 2017 locksteplabs.com Summary
  19. • How DHH Organizes His Rails Controllers
 http://jeromedalbert.com/how-dhh-organizes- his-rails-controllers/ •

    7 Patterns to Refactor Fat ActiveRecord Models
 http://blog.codeclimate.com/blog/2012/10/17/7- ways-to-decompose-fat-activerecord-models/ • Objects on Rails
 http://objectsonrails.com Deccan RubyConf 2017 locksteplabs.com Resources

More Decks by Michael Kohl

Other Decks in Programming