Rails 3Extra-hints
Summary● Rails 3   ○ Deprecations for Rails 4   ○ ActionMailer   ○ Ajax in Rails 3   ○ General...● Formtastic (2.2)   ○ De...
Rails 3 > DeprecationsPlugins will cease to existSolutions:● get the gem● insert plugin folder in /lib● insert somewhere e...
Rails 3 > DeprecationsActiveRecord ValidationsRails 2   validates_presence_of     :attr   validates_length_of       :attr,...
Rails 3 > DeprecationsAR queries● Rails 2ClassName.all(:conditions => ["blbla.id =?", 1])...● Rails 3   ○ Still supported,...
Rails 3 > Deprecationstable names● Rails 2:ClassName < ActiveRecord::Base   set_table_name :bang   ...end● Rails 3:ClassNa...
Rails 3 > Deprecations●   link_to :confirm option    Rails2: link_to ... :confirm => “Sure?”    Rails3: link_to ... :data ...
Rails 3 > Deprecationscomposed_of will be probably removed. Stillnot officially deprecated, but:http://blog.plataformatec....
Rails 3 > ActionMailer● mail delivery: created before delivered:Mailer.deliver_registry   #=> Mailer.registry.deliver● tem...
Rails 3 > Action Mailer- template variables are not passed explicitly tothe render@vars[:books] = ...body {:vars => @vars ...
Rails 3 > General● avoid "include_something" scopes -> just use ARel   method “includes” directlyClassName.include_books #...
Rails 3 > General● Rails.root can be joined directlyFile.join(Rails.root,‘bang’) #=> Rails.root.join(‘bang’)(note: Rails.r...
Rails 3 - General(Previous Rails 2 bug)Ajax (xhr) != "Script" (Content-Type)● JQuery’s $.get() does an asynchronous html r...
Rails 3 > General● rendering flush logic changed: template calls  with blocks that render something have to be  marked wit...
Rails 3 > General● URL helpers: clear distinction from url elements on   explicit assignment   ○ host : only host!     ■ r...
Rails 3 > General● ActiveRecord errors handled differently:   errors.on(:attr) #=> errors[:attr]● full asset paths:   comp...
Rails 3 > GeneralArel and Scopes● everything is concatenated, not only the conditions (as    in Rails 2)●   avoid defining...
Rails 3 > GeneralArel and Scopes● Rails 3 ARel bug: if you have a “group” call in your  ARel/scope definition and call “co...
Rails 3 > GeneralModulesRails 2:   module Bla         def self.included(base)             base.has_many ….             bas...
Rails 3 > GeneralModulesRails 3:   module Bla       extend ActiveSupport::Concern       included do            has_many   ...
Rails 3 > General● included from Concern module executes the code in the  block in the scope of the element where the modu...
Formtastic > Deprecations● explicit value for input now inside input_html   f.input :attr, :value => 3   f.input :attr, :i...
Formtastic - Hints● nested “inputs” calls on the same builder do  not work as before anymore:    f.inputs do       %li    ...
Formtastic - Hints● if an attribute is of type Integer, the resulting  input will be of type number (HTML5)Main Issues wit...
Formtastic - Custom Inputs● Input Structure changed - Focus on  modularity● All Standard Inputs include the Base Module● A...
Formtastic - Custom InputsCountry Select Box● Inherits From SelectInput, because it is a  select box● Additionally caches ...
Acts As Paranoid●   Different Gem●   Different Developers●   Different code-basis!●   More or less the same APInote: in or...
Will Paginate● array pagination is not available implicitly; if  you need it, you’ll have to require  ‘will_paginate/array...
RSpec● ‘double’ recommended instead of ‘mock’● Factory(:element) returns a stubbed model.  They neither have an id anymore...
ViewModels● module to include for view_model_for  access changed:include ViewModels::Helpers::Railsinclude ViewModels::Hel...
Inherited Resources● loading helpers on server start; not reloading  them on update; everytime you change  something in th...
Delayed Job● called differently:   ○ send_later :bang   #=>   delay.bang
Ruby 1.9● the new file character encoding system. new  to anyone? in new files that might not have  been marked with the u...
Ruby 1.9● “require” calls must be made using the full  path (or relative to the file where it is being  called)● when you ...
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.jo...
Assorted● forms that involve upload or possible upload  (more explicitly contain files, non-ASCII data,  and binary data) ...
Assorted● if there are functions that need to be shared between the  controller and its respective template rendering scop...
Assorted● Avoid writing explicit scopes (unless you  really really have too...)Class.where(“table_name.attribute = 1”) Cla...
More Hints?Check the documentation, and moreimportantly, pay attention to your developmentlog noise.                Questi...
Upcoming SlideShare
Loading in …5
×

Rails 3 hints

1,175 views
1,067 views

Published on

Some hints extracted from my experience porting rails 2 applications to rails 3

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,175
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Rails 3 hints

  1. 1. Rails 3Extra-hints
  2. 2. 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...
  3. 3. Rails 3 > DeprecationsPlugins will cease to existSolutions:● 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")
  4. 4. Rails 3 > DeprecationsActiveRecord ValidationsRails 2 validates_presence_of :attr validates_length_of :attr, :within => 2..60 validates_uniqueness_of :attr, :scope => [:assoc_id] …Rails 3 validates :attr, :presence => true, :length => {:within => 2..60}, :uniqueness => {:scope => :assoc_id}, ...
  5. 5. Rails 3 > DeprecationsAR queries● Rails 2ClassName.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)
  6. 6. Rails 3 > Deprecationstable names● Rails 2:ClassName < ActiveRecord::Base set_table_name :bang ...end● Rails 3:ClassName < ActiveRecord::Base self.table_name = :bang ...end
  7. 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. 8. Rails 3 > Deprecationscomposed_of will be probably removed. Stillnot officially deprecated, but:http://blog.plataformatec.com.br/2012/06/about-the-composed_of-removal/
  9. 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.hamltemplate_name.text.html.haml #=> template_name.html.haml
  10. 10. Rails 3 > Action Mailer- template variables are not passed explicitly tothe render@vars[:books] = ...body {:vars => @vars ...}#=>@books = ...
  11. 11. Rails 3 > General● avoid "include_something" scopes -> just use ARel method “includes” directlyClassName.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. 12. Rails 3 > General● Rails.root can be joined directlyFile.join(Rails.root,‘bang’) #=> Rails.root.join(‘bang’)(note: Rails.root is from type Pathname. Quoting thedocumentation: "All functionality from File, FileTest, andsome from Dir and FileUtils is included, in an unsurprisingway. It is essentially a facade for all of these, and more".)
  13. 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. 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. 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. 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. 17. Rails 3 > GeneralArel 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. 18. Rails 3 > GeneralArel 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 thatRightclearing::Song.count #=> 15269Rightclearing::Song.group_by(:album_title).count #=>{""=>2410, " Little pieces for guitars and otherinstruments - Part I"=>15, " so black, so bright-instrumental"=>6, ... }
  19. 19. Rails 3 > GeneralModulesRails 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. 20. Rails 3 > GeneralModulesRails 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. 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. 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. 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. 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. 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. 26. Formtastic - Custom InputsCountry 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. 27. Acts As Paranoid● Different Gem● Different Developers● Different code-basis!● More or less the same APInote: in order to use :with_deleted option for associationsin a class which is not paranoid itself, includeActsAsParanoid::Associations (seechange_tracking/change.rb model for an implementation)
  28. 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. 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. 30. 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)
  31. 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?
  32. 32. Delayed Job● called differently: ○ send_later :bang #=> delay.bang
  33. 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. 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. 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. 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. 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. 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. 39. More Hints?Check the documentation, and moreimportantly, pay attention to your developmentlog noise. Questions?

×