3. 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")
5. 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)
7. Rails 3 > Deprecations
● link_to :confirm option
Rails2: 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 :handlers
template: app/views/homepage/index.html.haml
name: :index / “index” / “homepage/index” … (extension out!)
formats: :html
handlers: :haml
render :index, :formats => :html, :handlers => :haml
if called in respond_to html block:
render :index, :handlers => :haml
if defined in environment that template engine is :haml:
render :index
8. 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/
9. 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.haml
template_name.text.html.haml #=> template_name.html.haml
10. Rails 3 > Action Mailer
- template variables are not passed explicitly to
the render
@vars[:books] = ...
body {:vars => @vars ...}
#=>
@books = ...
11. Rails 3 > General
● 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)
12. 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".)
13. Rails 3 - General
(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?
14. 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| %>
15. Rails 3 > General
● 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
16. Rails 3 > General
● 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
17. 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....
18. 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 #=> 15269
Rightclearing::Song.group_by(:album_title).count #=>
{""=>2410, " Little pieces for guitars and other
instruments - Part I"=>15, " so black, so bright-
instrumental"=>6, ... }
19. Rails 3 > General
Modules
Rails 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
20. Rails 3 > General
Modules
Rails 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
21. 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)
22. Formtastic > Deprecations
● explicit value for input now inside input_html
f.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 => ...
23. Formtastic - Hints
● nested “inputs” calls on the same builder do
not work as before anymore:
f.inputs do
%li
f.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)
24. 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.
25. 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
26. 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à!
27. 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)
28. 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
29. 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!
30. ViewModels
● module to include for view_model_for
access changed:
include ViewModels::Helpers::Rails
include ViewModels::Helpers::Mapping
● ViewModels gem is not being developed
further... use a new gem in RC instead?
(possible candidate: decorators)
31. 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?
33. 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 API
something.to_a => Array(something)
34. 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
35. 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={}|...}
36. 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 : {}
37. 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 ‘’
38. 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.
39. More Hints?
Check the documentation, and more
importantly, pay attention to your development
log noise.
Questions?