SlideShare uma empresa Scribd logo
1 de 39
Baixar para ler offline
Rails 3
Extra-hints
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...
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")
Rails 3 > Deprecations
ActiveRecord Validations

Rails 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},
                    ...
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)
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
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
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/
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
Rails 3 > Action Mailer
- template variables are not passed explicitly to
the render

@vars[:books] = ...
body {:vars => @vars ...}
#=>
@books = ...
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)
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".)
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?
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| %>
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
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
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....
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, ... }
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
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
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)
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 => ...
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)
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.
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
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à!
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)
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
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!
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)
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?
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 utf8 tag, please do.
  # -*- encoding : utf-8 -*-


● to_a removed from the Object API
  something.to_a => Array(something)
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
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={}|...}
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 : {}
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 ‘’
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.
More Hints?
Check the documentation, and more
importantly, pay attention to your development
log noise.




                Questions?

Mais conteúdo relacionado

Mais procurados

Ruby from zero to hero
Ruby from zero to heroRuby from zero to hero
Ruby from zero to heroDiego Lemos
 
Odoo (open erp) creating a module
Odoo (open erp) creating a moduleOdoo (open erp) creating a module
Odoo (open erp) creating a moduleTarun Behal
 
Swift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CSwift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CAlexis Gallagher
 
Esoft Metro Campus - Certificate in java basics
Esoft Metro Campus - Certificate in java basicsEsoft Metro Campus - Certificate in java basics
Esoft Metro Campus - Certificate in java basicsRasan Samarasinghe
 
Writing code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongVu Huy
 
perl course-in-mumbai
 perl course-in-mumbai perl course-in-mumbai
perl course-in-mumbaivibrantuser
 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...Fwdays
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation TutorialLorna Mitchell
 
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCECONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCEVenugopalavarma Raja
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to JavascriptAnjan Banda
 
Unbundling the JavaScript module bundler - DublinJS July 2018
Unbundling the JavaScript module bundler - DublinJS July 2018Unbundling the JavaScript module bundler - DublinJS July 2018
Unbundling the JavaScript module bundler - DublinJS July 2018Luciano Mammino
 
Working with Cocoa and Objective-C
Working with Cocoa and Objective-CWorking with Cocoa and Objective-C
Working with Cocoa and Objective-CKazunobu Tasaka
 
INHERITANCE IN C++ +2 COMPUTER SCIENCE CBSE AND STATE SYLLABUS
INHERITANCE IN C++ +2 COMPUTER SCIENCE CBSE AND STATE SYLLABUSINHERITANCE IN C++ +2 COMPUTER SCIENCE CBSE AND STATE SYLLABUS
INHERITANCE IN C++ +2 COMPUTER SCIENCE CBSE AND STATE SYLLABUSVenugopalavarma Raja
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Aaron Gustafson
 

Mais procurados (20)

Ruby from zero to hero
Ruby from zero to heroRuby from zero to hero
Ruby from zero to hero
 
Clojure 7-Languages
Clojure 7-LanguagesClojure 7-Languages
Clojure 7-Languages
 
Odoo (open erp) creating a module
Odoo (open erp) creating a moduleOdoo (open erp) creating a module
Odoo (open erp) creating a module
 
Swift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CSwift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-C
 
Esoft Metro Campus - Certificate in java basics
Esoft Metro Campus - Certificate in java basicsEsoft Metro Campus - Certificate in java basics
Esoft Metro Campus - Certificate in java basics
 
Writing code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen Luong
 
perl course-in-mumbai
 perl course-in-mumbai perl course-in-mumbai
perl course-in-mumbai
 
Java
Java Java
Java
 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
 
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCECONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
CONSTRUCTORS IN C++ +2 COMPUTER SCIENCE
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to Javascript
 
Introduction to Swift
Introduction to SwiftIntroduction to Swift
Introduction to Swift
 
Quick swift tour
Quick swift tourQuick swift tour
Quick swift tour
 
Unbundling the JavaScript module bundler - DublinJS July 2018
Unbundling the JavaScript module bundler - DublinJS July 2018Unbundling the JavaScript module bundler - DublinJS July 2018
Unbundling the JavaScript module bundler - DublinJS July 2018
 
Working with Cocoa and Objective-C
Working with Cocoa and Objective-CWorking with Cocoa and Objective-C
Working with Cocoa and Objective-C
 
INHERITANCE IN C++ +2 COMPUTER SCIENCE CBSE AND STATE SYLLABUS
INHERITANCE IN C++ +2 COMPUTER SCIENCE CBSE AND STATE SYLLABUSINHERITANCE IN C++ +2 COMPUTER SCIENCE CBSE AND STATE SYLLABUS
INHERITANCE IN C++ +2 COMPUTER SCIENCE CBSE AND STATE SYLLABUS
 
Lambda Functions in Java 8
Lambda Functions in Java 8Lambda Functions in Java 8
Lambda Functions in Java 8
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]
 

Destaque

Html standards presentation
Html standards presentationHtml standards presentation
Html standards presentationTiago Cardoso
 
10 Insightful Quotes On Designing A Better Customer Experience
10 Insightful Quotes On Designing A Better Customer Experience10 Insightful Quotes On Designing A Better Customer Experience
10 Insightful Quotes On Designing A Better Customer ExperienceYuan Wang
 
Learn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionLearn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionIn a Rocket
 
SEO: Getting Personal
SEO: Getting PersonalSEO: Getting Personal
SEO: Getting PersonalKirsty Hulse
 
How to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media PlanHow to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media PlanPost Planner
 
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika AldabaLightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldabaux singapore
 

Destaque (7)

Html standards presentation
Html standards presentationHtml standards presentation
Html standards presentation
 
Api presentation
Api presentationApi presentation
Api presentation
 
10 Insightful Quotes On Designing A Better Customer Experience
10 Insightful Quotes On Designing A Better Customer Experience10 Insightful Quotes On Designing A Better Customer Experience
10 Insightful Quotes On Designing A Better Customer Experience
 
Learn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionLearn BEM: CSS Naming Convention
Learn BEM: CSS Naming Convention
 
SEO: Getting Personal
SEO: Getting PersonalSEO: Getting Personal
SEO: Getting Personal
 
How to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media PlanHow to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media Plan
 
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika AldabaLightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
 

Semelhante a Rails 3 hints

HES2011 - joernchen - Ruby on Rails from a Code Auditor Perspective
HES2011 - joernchen - Ruby on Rails from a Code Auditor PerspectiveHES2011 - joernchen - Ruby on Rails from a Code Auditor Perspective
HES2011 - joernchen - Ruby on Rails from a Code Auditor PerspectiveHackito Ergo Sum
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Plataformatec
 
Ruby on Rails: Coding Guideline
Ruby on Rails: Coding GuidelineRuby on Rails: Coding Guideline
Ruby on Rails: Coding GuidelineNascenia IT
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best PracticesDavid Keener
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Clean code and refactoring
Clean code and refactoringClean code and refactoring
Clean code and refactoringYuriy Gerasimov
 
Ruby on Rails Security Updated (Rails 3) at RailsWayCon
Ruby on Rails Security Updated (Rails 3) at RailsWayConRuby on Rails Security Updated (Rails 3) at RailsWayCon
Ruby on Rails Security Updated (Rails 3) at RailsWayConheikowebers
 
Template rendering in rails
Template rendering in rails Template rendering in rails
Template rendering in rails Hung Wu Lo
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Clinton Dreisbach
 
Documenting from the Trenches
Documenting from the TrenchesDocumenting from the Trenches
Documenting from the TrenchesXavier Noria
 
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009Yasuko Ohba
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsEleanor McHugh
 
Intro to Rails ActiveRecord
Intro to Rails ActiveRecordIntro to Rails ActiveRecord
Intro to Rails ActiveRecordMark Menard
 

Semelhante a Rails 3 hints (20)

Intro to Rails 4
Intro to Rails 4Intro to Rails 4
Intro to Rails 4
 
HES2011 - joernchen - Ruby on Rails from a Code Auditor Perspective
HES2011 - joernchen - Ruby on Rails from a Code Auditor PerspectiveHES2011 - joernchen - Ruby on Rails from a Code Auditor Perspective
HES2011 - joernchen - Ruby on Rails from a Code Auditor Perspective
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010
 
Ruby on Rails: Coding Guideline
Ruby on Rails: Coding GuidelineRuby on Rails: Coding Guideline
Ruby on Rails: Coding Guideline
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
Rails Tips and Best Practices
Rails Tips and Best PracticesRails Tips and Best Practices
Rails Tips and Best Practices
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Clean code and refactoring
Clean code and refactoringClean code and refactoring
Clean code and refactoring
 
Ruby on Rails Security Updated (Rails 3) at RailsWayCon
Ruby on Rails Security Updated (Rails 3) at RailsWayConRuby on Rails Security Updated (Rails 3) at RailsWayCon
Ruby on Rails Security Updated (Rails 3) at RailsWayCon
 
Template rendering in rails
Template rendering in rails Template rendering in rails
Template rendering in rails
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 
Porting to Python 3
Porting to Python 3Porting to Python 3
Porting to Python 3
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
Documenting from the Trenches
Documenting from the TrenchesDocumenting from the Trenches
Documenting from the Trenches
 
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
Pragmatic Patterns of Ruby on Rails - Ruby Kaigi2009
 
Where's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord MigrationsWhere's My SQL? Designing Databases with ActiveRecord Migrations
Where's My SQL? Designing Databases with ActiveRecord Migrations
 
Intro to Rails ActiveRecord
Intro to Rails ActiveRecordIntro to Rails ActiveRecord
Intro to Rails ActiveRecord
 

Último

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 

Último (20)

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 

Rails 3 hints

  • 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. 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")
  • 4. Rails 3 > Deprecations ActiveRecord Validations Rails 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. 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)
  • 6. 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
  • 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?
  • 32. Delayed Job ● called differently: ○ send_later :bang #=> delay.bang
  • 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?