Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

The Ruby in Rails

The Ruby in Rails

Presented at the CorkDev user group.

Everyone has probably heard about Rails on Rails the web framework, but what is it about Ruby-the-language that enabled it? Why couldn’t Rails have come out of the Java world? Which features of Ruby produced such easy to read code? Which features enabled that famed ‘convention-over-configuration’ approach?

In this code-focused talk, I’ll show you the machinery behind lines from an example Rails app, explain how the language features work, and why they make Rails such a productive framework. I’ll cover symbols, blocks, iterators, meta-programming, and much more. But I’ll keep it simple as I’m also a bear of very little brain.

Avatar for Jamie Lawrence

Jamie Lawrence

August 14, 2014
Tweet

Other Decks in Technology

Transcript

  1. Ruby • a dynamic scripting language • elegant, natural, friendly

    • principle of least surprise • 21 years old (that's older than Java)
  2. 3.times do print "Ruby is easy!" end • No brackets

    (mostly optional) • No semicolons • Everything is an object • …that you call methods on
  3. Rails • is a web framework • built in Ruby

    • 10 years old! (no longer the new hotness) • convention over configuration • don't repeat yourself
  4. Models Represent rows in the database class User < ActiveRecord::Base

    has_many :projects validate_presence_of :username, :email end user = new User username: "jamie" user.email ='[email protected]' user.save User.find_by_username 'jamie'
  5. Views HTML templates (or json, or xml, or whatever) <!--

    show.html.erb --> <div> <ul> <% @user.projects.each do |project| %> <li><%= link_to project %></li> <% end %> </ul> </div>
  6. Controllers The meat of the application class UsersController < ApplicationController

    # /users/:username def show @user = Users.find_by_username params[:username] end end
  7. :symbols In our User class… validate_presence_of :username, :email Symbols are

    constant strings, a bit like public static final String in Java We could also have written: validate_presence_of 'username', 'email'
  8. :symbols everywhere • they look a little cleaner • they

    prevent memory allocation • no confusion about equality testing has_many :projects validates_presence_of :name, :if => :signed_in? before_filter :logged_in?, only: [:edit, :update] User.where :username => 'jamie', :email => '[email protected]'
  9. Hashes (Dictionaries, Hashmaps, whatever you call 'em') attrs = {

    :name => 'Jamie', :email => '[email protected]' } attrs[:name] #=> 'Jamie' attrs[:name] = 'James' Alternate Hash syntax attrs = { username: 'jamie', email: '[email protected]' }
  10. Hashes as the last argument User.where username: 'jamie', email: '[email protected]'

    This is passing a hash with the name and email keys to the where(opts) method Equivalent to: attrs = { :name => 'Jamie', :email => '[email protected]' } User.where attrs
  11. Missing Methods # from UsersController User.find_by_username 'jamie' Where was this

    method declared? It wasn't Whenever you call a method that doesn't exist, Ruby calls obj.method_missing with the method name and args …and you can override this :-)
  12. Missing Methods Found class User def method_missing name, args* column_name

    = name.match(/find_by_(\w+)/)[1] sql = "SELECT * FROM users WHERE #{column_name} = '#{args[0]}'" # query the database… end end User.find_by_username 'jamie' # SELECT * FROM users where username = 'jamie'
  13. Blocks 4.times do print 'Ruby ' end print 'Aha-aha-aaa' Blocks

    (do…end) are pieces of code that we can pass around to other methods @user.projects.each do |project| link_to project end
  14. Implementing .times class CorkDevNumber def initialize num @value = num

    end def times &block for i in 1..@value yield end end end CorkDevNumber.new(4).times do print 'Ruby ' end
  15. Meta-Programming Where did the user.projects method comes from? We didn't

    declare it! class User < ActiveRecord::Base has_many :projects end
  16. has_many methods has_many is a class-level method on ActiveRecord::Base. It

    creates new methods according the arguments we pass in when the class is loaded. projects projects=object projects_singular_ids projects<<(object, ...) projects.where(...) projects.create(attributes = {})
  17. Implementing has_many class Jamie def self.has_many things # getter define_method

    "#{things.to_s}" do @things end # setter define_method "#{things.to_s}=" do |value| @things = value end end end
  18. Ruby is simple in appearance, but is very complex inside,

    just like our human body. — Yukihiro Matsumoto (Matz)