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

Hidden gems in Ruby on Rails

Hidden gems in Ruby on Rails

Have you heard of a web framework called Ruby on Rails? There're a lot of stuff hidden under the hood of Ruby on Rails that you might not know about, and it might be really useful for you even if you aren't creating a web application. Let's not reimplement the wheel, and see what you can do if you include some part of Rails into your Ruby project.

Presented at RubyConf China 2013 on Oct 27, 2013.

Video is available at http://www.infoq.com/cn/presentations/hidden-gems-inside-those-of-Ruby-on-rails

F1c4a3bb1606cc4a61711e61e2fe6146?s=128

Prem Sichanugrist

October 27, 2013
Tweet

More Decks by Prem Sichanugrist

Other Decks in Programming

Transcript

  1. Hidden gems in Ruby on Rails

  2. Prem Sichanugrist ! ! @sikachu /sikachu

  3. None
  4. None
  5. ✈ ️ *57600x speed

  6. Flight attendance (Can speak Chinese)

  7. Me (Thai) Flight attendance (Can speak Chinese)

  8. 
 (Cannot speak Chinese) Flight attendance (Can speak Chinese) Me


  9. None
  10. 㟬૝ཁҰࠣ㠭佔吗?

  11. None
  12. Yes, I would like some coffee, please.

  13. 㟬૝ཁҰࠣ䑊༉҃౶?

  14. 㟬૝ཁҰࠣ䑊༉҃౶?

  15. Yes, cream and sugar is fine.

  16. 谢谢

  17. 䓟ཁෆཁ׃఺ॄ㜮?

  18. 䓟ཁෆཁ׃఺ॄ㜮?

  19. 㟬ت欢٣鸡೑҃ૉ৯?

  20. 㟬ت欢٣鸡೑҃ૉ৯?

  21. 㟬ت欢٣鸡೑҃ૉ৯?

  22. 㟬ت欢٣鸡೑҃ૉ৯?

  23. 㟬ت欢٣鸡೑҃ૉ৯?

  24. None
  25. "Let's count how many people trying to speak Chinese to

    me"
  26. "This is going to be fun"

  27. I lost my count

  28. It feels great!

  29. 谢谢

  30. Hidden gems in Ruby on Rails

  31. None
  32. None
  33. None
  34. None
  35. None
  36. None
  37. None
  38. "Rails is HUGE"

  39. None
  40. None
  41. Rails is modular

  42. Pick only part you use

  43. "I'm not doing web application"

  44. None
  45. Use Rails' components

  46. Actively maintained

  47. Fully tested

  48. "I'll implement them myself"

  49. gem  install  rails

  50. Rails • Action Mailer • Action Pack • Active Record

    • Active Model • Active Support • Railties
  51. Rails • Action Mailer • Action Pack • Active Record

    • Active Model • Active Support • Railties
  52. gem  "mail"

  53. Rails • Action Mailer • Action Pack • Active Record

    • Active Model • Active Support • Railties
  54. Action Pack

  55. Action Dispatch Middleware

  56. [master][~/Projects/rails] ls \ > actionpack/lib/action_dispatch/middleware callbacks.rb public_exceptions.rb ssl.rb cookies.rb reloader.rb

    stack.rb debug_exceptions.rb remote_ip.rb static.rb exception_wrapper.rb request_id.rb templates flash.rb session params_parser.rb show_exceptions.rb
  57. ActionDispatch::ShowException Rescue and display the exception message

  58. ActionDispatch::SSL Redirects all non-SSL requests to HTTPS

  59. ActionDispatch::Static Serves static file in the path

  60. Active Record

  61. Pick one: • Active Record • DataMapper • Sequel •

    NoSQL varieties
  62. Don't write raw SQL yourself

  63. http://xkcd.com/327/

  64. Active Model

  65. ActiveModel::Model

  66. Makes PORO acts
 like a model (PORO = Plain Old

    Ruby Object)
  67. ActiveModel::Model • Naming helpers • I18n support • Validation

  68. class  Person      include  ActiveModel::Model      attr_accesssor  :name,

     :age   end       person  =  Person.new(name:  "Prem",  age:  27)   person.valid?  #=>  true   person.name  #=>  "Prem"
  69. ActiveModel::Model • Naming helpers • I18n support • Validation

  70. ActiveModel::Validations

  71. Add validations to PORO

  72. class  Person      include  ActiveModel::Validations        

     attr_accessor  :name,  :age      validates  :name,  presence:  true      validates  :age,  numericality:  true   end   ! ! !
  73. class  Person      include  ActiveModel::Validations        

     attr_accessor  :name,  :age      validates  :name,  presence:  true      validates  :age,  numericality:  true   end   ! person  =  Person.new   person.name  =  ""   person.valid?  #=>  false
  74. Active Support

  75. Core Extensions

  76. String

  77. String#inquiry

  78. country  =  'china'   country  =  country.inquiry   ! country.china?

     #=>  true   country.usa?  #=>  false
  79. String#squish

  80. very_complex_sql  =  <<-­‐SQL      SELECT  *      FROM

     posts      WHERE  state='published'   SQL   ! #  =>  "    SELECT  *\n    FROM  posts\n     WHERE  state='published'\n"
  81. very_complex_sql  =  <<-­‐SQL.squish      SELECT  *      FROM

     posts      WHERE  state='published'   SQL   ! #  =>  "SELECT  *  FROM  posts  WHERE   state='published'"
  82. String#strip_heredoc

  83. content  =  <<-­‐README      Hello        

     World!   README   ! #=>  "    Hello\n        World!\n"
  84. class  FancyHello      def  initialize(user)        

     if  should_say_hello_to?  user              content  =  <<-­‐README                  Hello                      World!              README          end      end   end   ! #=>  "                Hello\n                    World!\
  85. class  FancyHello      def  initialize(user)        

     if  should_say_hello_to?  user              content  =  <<-­‐README   Hello      World!   README          end      end   end   ! #=>  "Hello\n    World!\n"
  86. content  =  <<-­‐README.strip_heredoc      Hello        

     World!   README   #=>  "Hello\n    World!\n"
  87. String#to_date String#to_datetime String#to_time

  88. Date.parse('2013-­‐10-­‐27')   #=>  Sun,  27  Oct  2013   '2013-­‐10-­‐27'.to_date  

    #=>  Sun,  27  Oct  2013       DateTime.parse('2013-­‐10-­‐27  09:40:00')   #=>  Sun,  27  Oct  2013  09:40:00  +0000   '2013-­‐10-­‐27  09:40:00'.to_datetime   #=>  Sun,  27  Oct  2013  09:40:00  +0000       Time.parse('09:40:00')   #=>  2013-­‐10-­‐27  09:40:00  +0800   '09:00:00'.to_time   #=>  2013-­‐10-­‐27  09:40:00  +0800
  89. Hash

  90. Hash#transform_keys

  91. hash  =  {  foo:  'foo',  bar:  'bar'  }   #=>

     {:foo=>"foo",  :bar=>"bar"}   ! hash.transform_keys  {  |key|      key.to_s.capitalize  }   #=>  {"Foo"=>"foo",  "Bar"=>"bar"}
  92. Array

  93. Array#extract_options   Array#extract_options!

  94. Keyword arguments Until we all using Ruby 2.0

  95. #  say_hello("John",  "Jane",  language:  "zh-­‐CN")   def  say_hello(*names_or_options)    

     if  names_or_options.last.is_a?(Hash)          options  =  names_or_options.pop          names  =  names_or_options      else          options  =  {}          names  =  names_or_options      end          case  options[:language]      #  ...  
  96. #  say_hello("John",  "Jane",  language:  "zh-­‐CN")   def  say_hello(*names)    

     options  =  names.extract_options!            case  options[:language]      #  ...  
  97. #  say_hello("John",  "Jane",  language:  "zh-­‐CN")   def  say_hello(*names,  language:  "en-­‐US")

         case  language      #  ...   ! !
  98. Array#in_groups

  99. %w(1  2  3  4  5  6  7  8  9  10).in_groups(3)

      #  =>  [   #            [1,  2,  3,  4],   #            [5,  6,  7,  nil],   #            [8,  9,  10,  nil]   #        ]
  100. Array#in_groups_of

  101. %w(1  2  3  4  5  6  7  8  9  10).in_groups_of(3)

      #  =>  [   #            [1,  2,  3],   #            [4,  5,  6],   #            [7,  8,  9],   #            [10,  nil,  nil]   #        ]  
  102. Object

  103. Object#in?

  104. STARTING_POKEMONS  =  %w(Chespin  Fennekin  Froakie)       if  STARTING_POKEMONS.include?(current_pokemon)

         #  ...   end
  105. STARTING_POKEMONS  =  %w(Chespin  Fennekin  Froakie)       if  current_pokemon.in?(STARTING_POKEMONS)

         #  ...   end
  106. Object#blank?   Object#present?

  107. str  =  nil   str.nil?  #=>  true   str.empty?  #=>

     NoMethodError   str.blank?  #=>  true   str.present?  #=>  false       str  =  ""   str.nil?  #=>  false   str.empty?  #=>  true   str.blank?  #=>  true   str.present?  #=>  false       str  =  "Hello"   str.nil?  #=>  false   str.empty?  #=>  false   str.blank?  #=>  false   str.present?  #=>  true
  108. Disclaimer

  109. Active Support is lazy-loaded

  110. require  "active_support"

  111. require  "active_support"   "Hello".inquiry   !

  112. require  "active_support"   "Hello".inquiry   #=>  NoMethodError:  undefined  method  

    `inquiry'  for  "Hello":String
  113. require  "active_support"   "Hello".inquiry   #=>  NoMethodError:  undefined  method  

    `inquiry'  for  "Hello":String
  114. require  "active_support/all"

  115. require  "active_support/all"

  116. None
  117. None
  118. require  "active_support/core_ext/string/inquiry"

  119. require  "active_support/core_ext/string"

  120. http://guides.rubyonrails.org

  121. Thank you! Prem Sichanugrist
 (@sikachu) http://learn.thoughtbot.com
 20% off promotion Code:

    RUBYCONFCHINA I also have some stickers