Slide 1

Slide 1 text

Ruby Roundup Oct/2012 Rails 4 & more Rida Al Barazi Ruby Brigade Toronto @rida

Slide 2

Slide 2 text

Rida! • Senior Ruby on Rails Developer • Works at Wave Accounting Inc. • Author of Beginning Rails 3 Book • @rida on Twitter

Slide 3

Slide 3 text

Rails 4

Slide 4

Slide 4 text

Rails 4 - Object#try and Object#try! Object#try will now return nil instead of raising a NoMethodError if the receiving object does not implement the method, but you can still get the old behavior by using the new Object#try!.

Slide 5

Slide 5 text

Rails 4 - Concerns in routing concern :commentable do resources :comments end concern :image_attachable do resources :images, only: :index end # These concerns are used in Resources routing: resources :messages, concerns: [:commentable, :image_attachable] # or in a scope or namespace: namespace :posts do concerns :commentable end

Slide 6

Slide 6 text

Rails 4 - ActionController::Live class FooController < ActionController::Base include ActionController::Live def index 100.times { # Client will see this as it's written response.stream.write "hello world\n" sleep 1 } response.stream.close end end

Slide 7

Slide 7 text

Rails 4 - Join table migration rails g migration CreateMediaJoinTable artists musics:uniq # will create a migration with create_join_table :artists, :musics do |t| # t.index [:artist_id, :music_id] t.index [:music_id, :artist_id], unique: true end

Slide 8

Slide 8 text

Rails 4 - Associations conditions has_many :popular_grouped_posts, :include => :comments, :class_name => "Post", :group => "type", :having => "SUM(comments_count) > 1", :select => "type" # Will become has_many :popular_grouped_posts, -> { includes(:comments). group("type"). having("SUM(comments_count) > 1"). select("type") }, :class_name => "Post"

Slide 9

Slide 9 text

Rails 4 - ActionController::Flash.add_flash_types class ApplicationController add_flash_types :error, :warning end # If you add the above code, you can use <%= error %> in an erb, # and rediect_to /foo, :error => 'message' in a controller.

Slide 10

Slide 10 text

Rails 4 - ActiveRecord::Relation#pluck Person.pluck(:id, :name) # SELECT people.id, people.name FROM people # [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]

Slide 11

Slide 11 text

Rails 4 - rails new # Added a generator option to remove the public/index.html file when generating a new Rails application -i, [--skip-index-html] # Skip public/index.html file

Slide 12

Slide 12 text

Rails 4 - logger.push_tags and .pop_tags class Job def before Rails.logger.push_tags :jobs, self.class.name end def after Rails.logger.pop_tags 2 end end

Slide 13

Slide 13 text

Rails 4 - form helpers - collection_check_boxes collection_check_boxes :post, :author_ids, Author.all, :id, :name # Outputs something like: # # D. Heinemeier Hansson # # D. Thomas # # The label/check_box pairs can be customized with a block.

Slide 14

Slide 14 text

Rails 4 - form helpers - collection_radio_buttons collection_radio_buttons :post, :author_id, Author.all, :id, :name # Outputs something like: # # D. Heinemeier Hansson # # D. Thomas # The label/radio_button pairs can be customized with a block.

Slide 15

Slide 15 text

Rails 4 - Live reload! http://www.youtube.com/watch?v=njO2qeN0pO4

Slide 16

Slide 16 text

Rails 4 - Rails.queue class MassEmailTheInterwebs def run # some nasty code here end end Rails.queue.push(MassEmailTheInterwebs.new) # Config config.queue = Sidekiq::Client::Queue # default: ActiveSupport::Queue

Slide 17

Slide 17 text

Rails 4 - strong_parameters vs attr_accessible # before class Post < ActiveRecord::Base attr_accessible :title, :body end # after class Post < ActiveRecord::Base end class PostsController < ApplicationController def create @post = Post.create(post_params) end private def post_params params.permit(:title, :body) end end end

Slide 18

Slide 18 text

Ruby Gems

Slide 19

Slide 19 text

Talks # Talks gem — now your ruby and command-line tools can talk with you # ~/.talksrc bundle: voice: 'vicki' before_message: 'Bundler again will do all right' after_message: "Bundler's job is done here" before_notify: 'This will go to notification before `before_message`' after_notify: 'This will go to notification after `after_message`' $ talking bundle install https://github.com/gazay/talks

Slide 20

Slide 20 text

Letter Opener # First add the gem to your development environment # and run the bundle command to install it. gem "letter_opener", :group => :development # Then set the delivery method in # config/environments/development.rb config.action_mailer.delivery_method = :letter_opener # Now any email will pop up in your browser instead of being sent. # The messages are stored in tmp/letter_opener. https://github.com/ryanb/letter_opener

Slide 21

Slide 21 text

Seed Dump $ rake db:seed:dump MODELS=User,Product LIMIT=2 # Autogenerated by the db:seed:dump task # Do not hesitate to tweak this to your needs products = Product.create([ { :category_id => 1, :description => "Long Sleeve Shirt", :name => "Long Sleeve Shirt" }, { :category_id => 3, :description => "Plain White Tee Shirt", :name => "Plain T-Shirt" } ]) users = User.create([ { :id => 1, :password => "123456", :username => "test_1" }, { :id => 2, :password => "234567", :username => "tes2" } ]) https://github.com/rhalff/seed_dump

Slide 22

Slide 22 text

Divergence # Map subdomains to git branches for switching live codebases on the fly. # It's a Rack application that acts as a HTTP proxy between you and your # web application for rapid testing. Divergence::Application.configure do |config| config.git_path = "/path/to/git_root" config.app_path = "/path/to/app_root" config.cache_path = "/path/to/cache_root" config.callbacks :on_branch_discover do |subdomain| case subdomain when "release-1" "test_branch" when "release-2" "other_branch" end end end https://github.com/layervault/divergence

Slide 23

Slide 23 text

Api matchers "{ 'transaction': { 'id': '54', 'status': 'paid' } }".should have_node(:transaction) "{ 'transaction': { 'id': '54', 'status': 'paid' } }".should have_node(:id).with(54) "{ 'error': 'not_authorized' }".should have_node(:error).with('not_authorized') '{"parcels":1 }'.should have_node(:parcels).with(1) '{"error": "Transaction error: Name cant be blank"}'.should have_node(:error).including_text("Transaction error") https://github.com/tomas-stefano/api_matchers

Slide 24

Slide 24 text

Thank you! Rida Al Barazi Ruby Brigade Toronto @rida