Download - Rails 3 hints
![Page 1: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/1.jpg)
Rails 3Extra-hints
![Page 2: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/2.jpg)
Summary● Rails 3
○ Deprecations for Rails 4○ ActionMailer○ Ajax in Rails 3○ General...
● Formtastic (2.2)○ Deprecations for V.3○ Custom Inputs
● Acts as Paranoid● Will Paginate● Rspec● ViewModels● Inherited Resources● Delayed Job● Ruby 1.9● Assorted...
![Page 3: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/3.jpg)
Rails 3 > Deprecations
Plugins will cease to exist
Solutions:● get the gem● insert plugin folder in /lib● insert somewhere else and bundle them in your gemfile:
gem "view_models", "=2.0.1", :path => File.join(File.dirname(__FILE__), "/vendor/modified_gems/view_models-2.0.1")
![Page 4: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/4.jpg)
Rails 3 > Deprecations
ActiveRecord Validations
Rails 2validates_presence_of :attrvalidates_length_of :attr, :within => 2..60validates_uniqueness_of :attr, :scope => [:assoc_id]
…Rails 3
validates :attr, :presence => true, :length => {:within => 2..60}, :uniqueness => {:scope => :assoc_id}, ...
![Page 5: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/5.jpg)
Rails 3 > Deprecations
AR queries● Rails 2
ClassName.all(:conditions => ["blbla.id = ?", 1])...● Rails 3
○ Still supported, but it is just translating to ARel. Support in Rails 4 is still unknown.
ClassName.where("blbla.id = ?", 1)
![Page 6: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/6.jpg)
Rails 3 > Deprecations
table names● Rails 2:ClassName < ActiveRecord::Base
set_table_name :bang...
end
● Rails 3:ClassName < ActiveRecord::Base
self.table_name = :bang...
end
![Page 7: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/7.jpg)
Rails 3 > Deprecations
● link_to :confirm optionRails2: link_to ... :confirm => “Sure?” Rails3: link_to ... :data => {:confirm => “Sure?”}
● url helper accept :format option => :html, :js, :json, :xml, etc...
● render accepts two extra options: :formats and :handlerstemplate: app/views/homepage/index.html.hamlname: :index / “index” / “homepage/index” … (extension out!)formats: :htmlhandlers: :hamlrender :index, :formats => :html, :handlers => :haml
if called in respond_to html block:render :index, :handlers => :hamlif defined in environment that template engine is :haml:render :index
![Page 8: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/8.jpg)
Rails 3 > Deprecations
composed_of will be probably removed. Still not officially deprecated, but:
http://blog.plataformatec.com.br/2012/06/about-the-composed_of-removal/
![Page 9: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/9.jpg)
Rails 3 > ActionMailer
● mail delivery: created before delivered:
Mailer.deliver_registry #=> Mailer.registry.deliver
● template extensions changed:
template_name.text.plain.haml #=> template_name.text.hamltemplate_name.text.html.haml #=> template_name.html.haml
![Page 10: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/10.jpg)
Rails 3 > Action Mailer
- template variables are not passed explicitly to the render
@vars[:books] = ...body {:vars => @vars ...}#=>@books = ...
![Page 11: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/11.jpg)
● avoid "include_something" scopes -> just use ARel method “includes” directly
ClassName.include_books #=> ClassName.includes(:books)
● RJS is gone○ when writing ".js" templates, every ruby block
inserted has to be explicitly escaped (escape_javascript)
RAILS_ENV, RAILS_ROOT, RAILS_DEFAULT_LOGGER (Strings)Rails.env, Rails.root, Rails.logger (Pathnames)
Rails 3 > General
![Page 12: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/12.jpg)
Rails 3 > General
● Rails.root can be joined directly
File.join(Rails.root,‘bang’) #=> Rails.root.join(‘bang’)
(note: Rails.root is from type Pathname. Quoting the documentation: "All functionality from File, FileTest, and some from Dir and FileUtils is included, in an unsurprising way. It is essentially a facade for all of these, and more".)
![Page 13: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/13.jpg)
(Previous Rails 2 bug)
Ajax (xhr) != "Script" (Content-Type)● JQuery’s $.get() does an asynchronous html request. Rails will build the
response body in html format (assuming type is not given to $.get)
● JQuery’s $.getScript() does an asynchronous script request. Rails will build the response in the js format
● JQuery’s $.getJSON() does an asynchronous json request. Rails will build the response in the json format
● ...
● you get the idea
● if you want to test if the request was asynchronous in the controller, use request.xhr?
Rails 3 - General
![Page 14: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/14.jpg)
Rails 3 > General
● rendering flush logic changed: template calls with blocks that render something have to be marked with “=” ; others with “-” (Haml notation):
in ERB:<%= form_for(...) do %>...<% @elements.each do |element| %>
![Page 15: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/15.jpg)
● URL helpers: clear distinction from url elements on explicit assignment
○ host : only host! ■ restorm.dev:3000 -> host is restorm.dev
○ subdomain : only subdomain!■ choco.restorm.com -> subdomain is choco■ us.members.restorm.com -> subdomain is us.
members○ port : only port!
■ restorm.dev:3000 -> port is 3000○ user ; password; ... you get the idea
Rails 3 > General
![Page 16: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/16.jpg)
● ActiveRecord errors handled differently:errors.on(:attr) #=> errors[:attr]
● full asset paths: compute_asset_url(“/images/image.jpg”) #=> image_path(“/images/image.jpg”)
● form calls where we want to define the variable name explicitly works differently in Rails 3:form_for :song, elem #=> form_for elem, :as => :song
● Array “random” function was removed; use “sample” instead:[1, 2, 3].random #=> [1, 2, 3].sample
Rails 3 > General
![Page 17: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/17.jpg)
Rails 3 > General
Arel and Scopes
● everything is concatenated, not only the conditions (as in Rails 2)
● avoid defining a condition like select(“table_name.*”); it does that already by default
● (related to above) avoid defining “select” calls in scopes whenever possible; everytime you concatenate it with another “select” call, they will be joined “SELECT *, id FROM...“ #=> WRONG!
● same thing for “order” calls, “group” calls, etc....
![Page 18: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/18.jpg)
Rails 3 > General
Arel and Scopes
● Rails 3 ARel bug: if you have a “group” call in your ARel/scope definition and call “count” at the end, it will not return an Integer, but an OrderedHash (?), careful with that
Rightclearing::Song.count #=> 15269Rightclearing::Song.group_by(:album_title).count #=> {""=>2410, " Little pieces for guitars and other instruments - Part I"=>15, " so black, so bright-instrumental"=>6, ... }
![Page 19: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/19.jpg)
Rails 3 > General
ModulesRails 2:
module Bla
def self.included(base)
base.has_many ….
base.send :include, InstanceMethods
base.extend ClassMethods
end
module ClassMethods
end
module InstanceMethods
def bang
end
end
end
![Page 20: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/20.jpg)
Rails 3 > General
ModulesRails 3:
module Bla
extend ActiveSupport::Concern
included do
has_many
# include InstanceMethods, but, it does this implicitly
extend ClassMethods
end
module ClassMethods
end
def bang
end
end
![Page 21: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/21.jpg)
Rails 3 > General● included from Concern module executes the code in the
block in the scope of the element where the module is included (no more need for the “send :included” call that breaks visibility);
● different order of inclusion (may be an issue in certain cases where we have hacked stuff for inherited resources and other gems...)
● functions defined directly in the module will be instance methods implicitly in the class where the module is included (no more need for the explicit module InstanceMethods)
![Page 22: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/22.jpg)
Formtastic > Deprecations
● explicit value for input now inside input_htmlf.input :attr, :value => 3 f.input :attr, :input_html => { :value => 3 }
● input for dates is now called :date_select● buttons defined differently:
f.buttons do... #=> f.actions do ...f.commit_button #=> f.action :submit #=> <input type=submit...../>f.commit_button :button_html =>... #=> f.action :submit, :as => :button, :button_html => ...
![Page 23: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/23.jpg)
Formtastic - Hints
● nested “inputs” calls on the same builder do not work as before anymore:f.inputs do
%lif.inputs do
….WRONG!
● Notes:
● does not produce invalid HTML as before (good)
● produces nevertheless HTML, though unexpected (so so...)
● does not produce warning message (bad)
![Page 24: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/24.jpg)
Formtastic - Hints
● if an attribute is of type Integer, the resulting input will be of type number (HTML5)
Main Issues with this:○ Some JS code was dependent of the input type
being "text"
Ways to avoid it:○ Provide a context to the element instead of
depending of it directly; mark elements with a class.
![Page 25: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/25.jpg)
Formtastic - Custom Inputs
● Input Structure changed - Focus on modularity
● All Standard Inputs include the Base Module● All Standard Inputs define the to_html which
renders the input● Separate Modules defining input validations,
labelling, content wrapping, errors, collection, etc...
● Everything can be overwritten/redefined
![Page 26: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/26.jpg)
Formtastic - Custom Inputs
Country Select Box
● Inherits From SelectInput, because it is a select box
● Additionally caches the countries and calls them in the "collection" method, which is used by the parent to render the select box
...Et Voilà!
![Page 27: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/27.jpg)
Acts As Paranoid
● Different Gem● Different Developers● Different code-basis! ● More or less the same API
note: in order to use :with_deleted option for associations in a class which is not paranoid itself, include ActsAsParanoid::Associations (see change_tracking/change.rb model for an implementation)
![Page 28: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/28.jpg)
Will Paginate
● array pagination is not available implicitly; if you need it, you’ll have to require ‘will_paginate/array’ explicitly in the file using it
● https://github.com/mislav/will_paginate/wiki/Backwards-incompatibility
![Page 29: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/29.jpg)
RSpec
● ‘double’ recommended instead of ‘mock’● Factory(:element) returns a stubbed model.
They neither have an id anymore nor they can be saved anymore.
● One cannot stub :id calls:
○ Factory(:model, :id => 23) is not valid!
![Page 30: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/30.jpg)
ViewModels
● module to include for view_model_for access changed:
include ViewModels::Helpers::Railsinclude ViewModels::Helpers::Mapping
● ViewModels gem is not being developed further... use a new gem in RC instead? (possible candidate: decorators)
![Page 31: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/31.jpg)
Inherited Resources
● loading helpers on server start; not reloading them on update; everytime you change something in the helpers, you’ll have to restart the server (Major downer...)
● Deprecated; Gem creator recommends using the new Rails 3 controllers ; consider removal in RC?
![Page 32: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/32.jpg)
Delayed Job
● called differently: ○ send_later :bang #=> delay.bang
![Page 33: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/33.jpg)
Ruby 1.9
● the new file character encoding system. new to anyone? in new files that might not have been marked with the utf8 tag, please do.# -*- encoding : utf-8 -*-
● to_a removed from the Object APIsomething.to_a => Array(something)
![Page 34: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/34.jpg)
Ruby 1.9
● “require” calls must be made using the full path (or relative to the file where it is being called)
● when you return something from a Proc, you are not returning it from the Proc, but instead from the scope where the Proc is being executed ○ no scope is returning now
![Page 35: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/35.jpg)
Ruby 1.9
● Array#to_s works differently:○ Ruby 1.8 - [1, 2].to_s #=> “12”○ Ruby 1.9 - [1.2].to_s #=> “[1, 2]”○ use.join instead
● procs now support splat arguments and default values for them:○ proc {|id, args*, opts={}|...}
![Page 36: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/36.jpg)
Assorted
● forms that involve upload or possible upload (more explicitly contain files, non-ASCII data, and binary data) should be marked as multipart.
● in cases where the method arguments are defined with a pointer (“def func(*args)”) and we want to extract the options hash from the last argument:opts = args.extract_options!opts = args.last.is_a?(Hash) ? args.pop : {}
![Page 37: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/37.jpg)
Assorted
● if there are functions that need to be shared between the controller and its respective template rendering scope (templates, helpers), use the helper_method method and define it only one time in the controller.
● Avoid inclusion of helpers in controllers; either they are helpers and therefore should support the rendering, or they are controller mixins that are responsible for handling controller code (and may define helper functions using the helper_method method mentioned above)
● use always t(“a.b.c.d”) instead of t(:d => :scope => [:a, :b, :c]) it is better to look for..and use always “” and not ‘’
![Page 38: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/38.jpg)
Assorted
● Avoid writing explicit scopes (unless you really really have too...)
Class.where(“table_name.attribute = 1”) Class.where(:attribute => 1)
● Why? ○ ARel sanitizes everything ○ ARel gets the table names and attribute names from
the table structure by itself○ (very important!) ARel quotes the table name,
attribute name and value all by himself (something we seldom do).
● Implicitly protects us from SQL injection, table name changing and usage of SQL reserved words.
![Page 39: Rails 3 hints](https://reader034.vdocuments.us/reader034/viewer/2022042509/54bd178e4a7959135f8b45a7/html5/thumbnails/39.jpg)
Questions?
Check the documentation, and more importantly, pay attention to your development log noise.
More Hints?