CSC/ECE 517 Fall 2014/ch1a 21 as

From Expertiza_Wiki
Jump to navigation Jump to search

Differences between Rails 3 and Rails 4

Introduction<ref>http://en.wikipedia.org/wiki/Ruby_on_Rails</ref>

Ruby on rails, or simply Rails, is a popular open source cross platform web application framework written in Ruby. Rails follows many well-known software engineering patterns and paradigms including Configuration over Convention, Don't Repeat Yourself, Model View Controller, Active record pattern.

Background

David Heinemeier Hansson created Ruby on Rails from his work at Basecamp in 2003. It started receiving major attention after Apple decided that it will ship Ruby on Rails with every Mac OS X in 2006. After a brief collaboration with Merb, another web application framework, Rails 3.0 was released on August 29, 2010, with Reversible Database Migrations, Asset Pipeline, Streaming, jQuery as default JavaScript library and newly introduced CoffeeScript and Sass into the stack added in the later iterations. Rails 4.0 was released on June 25, 2013, introducing Russian Doll Caching, Turbolinks, Live Streaming as well as making Active Resource, Active Record Observer and other components optional by splitting them as gems. Rails 4.0 dropped support for 1.8.7 and added Ruby 1.9.3 to its minimum requirements.

Changes from 3 to 4

1. Native Data Types In PostgreSQL<ref>http://blog.remarkablelabs.com/2012/12/a-love-affair-with-postgresql-rails-4-countdown-to-2013</ref>

Out of all the databases that are supported in ActiveRecord, PostgreSQL received the maximum attention during the development of Rails 4. Rails 4 supports hstore which allows you store a set of key-hash pairs within a single postgreSQL value. In other words, it allows you to have NoSQL schema-less data support in PostgreSQL.New data types can be easily created by executing "create extension <dataTypeName>" command. If the attribute we are listing is an array then it can simply be done by adding array:true to the attribute.


2. Article.find_by<ref>http://blog.remarkablelabs.com/2012/12/what-s-new-in-active-record-rails-4-countdown-to-2013</ref>

In Rails 3.0, we could use a column name to search which relied on method missing. Active Record, in previous versions of Rails, provided a finder method for every column in the table. For example, if you had an Email field in the Person model, then it was possible to execute Person.find_by_email('abc@xyz.com'). Rails 4 uses Hash instead of its implementation in Rails 3. Examples :

Rails 3: Team.find_all_by_name('Justice League') 
Rails 4: Team.where(name: 'Justice League') 

Rails 3: Team.find_or_create_by_name('Justice League') 
Rails 4: Team.where(name: 'Justice League').first_or_create 

methods find_by and find_by! have been added to Rails 4.

Member.find_by name: 'Batman', city: 'Gotham' 
Member.find_by! name: 'Superman' 

3. Strong Parameters

A primary feature of Rails has always been the ability to sanitize user input coming from ubiquitous forms. However, untill Rails3, accessible fields had to be listed in the models. In Rails 4, Strong parameters allow higher control over the content. Example: Generally, Every request wraps its parameters in ActionController:parameters which allows whitelisting of specific keys. If one tries to use them directly, they will get ActiveModel::ForbiddenAttributesError.

params = ActionController::Parameters.new(username: "john") 
User.new(params) 
# => ActiveModel::ForbiddenAttributesError

The attributes which are required in mass assignment can be whitelisted to get rid of the error.

params = ActionController::Parameters.new(username: "john") 
> User.new(params.permit(:username)) 

Whitelisting each and every parameter is not mandatory. However, not enlisting one will generate the forbidden attributes error. When using permit, if the permitted attribute is missing, it won’t throw any error.

params = ActionController::Parameters.new(username: "john", password: "secret") 
params.permit(:username, :password, :foobar) 
# => { "username" => "john", "password" => "secret" } 

If a parameter has to be present, Require command instead of permit is used.

params.require(:foobar) 
# ActionController::ParameterMissing: param not found: foobar 

An advantage of this approach is that it allows us to filter different parameters in a user facing action than in an admin area. Also, different actions could permit different sets of allowed attributes. Having the controller in charge of what the model receives makes sense.

4. ACTIVERECORD::SESSIONSTORE

Storing sessions in a database may be useful in certain application but is not as efficient as cookies. Another issue with session storage is it is not scalable and puts stress on database when huge number of read/writes are being done simultaneously. Thus,Rails 4 has stopped support for ACTIVERECORD::SESSIONSTORE. This functionality can still be achieved with the help of a gem by using 'activerecord-session_store' gem.

5. Concerns Directory<ref>http://www.sitepoint.com/get-your-app-ready-for-rails-4/</ref>

Rails 4 provides a new pattern to avoid code repetition. When there are multiple resources or methods shared between routes, there is also a high amount of code repetition. This feature gives a new concern definition on routes, which helps improve the readability and makes code more DRY.

Rails 3.2

 resources :messages  do 
  resources :comments  
  post :trash, :restore, on: :member  
end  
 resources :documents do  
  resources :comments  
  post :trash, :restore, on: :member  
end  
 

Rails 4

concern :commentable do  
  resources :comments  
end  
 
concern :trashable do  
  post :trash, :restore, on: :member  
end 
 
resources :messages, :documents, concerns: [:commentable, :trashable] 

This can be used in Rails 3.2 by simply adding the routing_concerns gem to your app. Thus, Concerns help to reduce large models.

6. Active model<ref>http://api.rubyonrails.org/classes/ActiveModel/Model.html</ref>

Untill Rails 3,If a developer wanted to have an object interact with Action Pack, it required inclusion of many modules. This would produce high redundancy and fragile application that broke on upgrades. In Rails 4, it can be done with include ActiveModel::Model, like in active record but not backed by db.ActiveModel::Model is a module mixin that allows Ruby objects to work with Action Pack. Classes that include ActiveModel::Model also get several Active Model features such as:Model name introspections, Conversions, Translations, Validations. It allows you to initialize the object with a hash of attributes, pretty much like ActiveRecord does.Active Model provides a known set of interfaces for usage in model classes. They allow for Action Pack helpers to interact with non-Active Record models

class Person
  include ActiveModel::Model

  attr_accessor :name, :age
  validates_presence_of :name
end
Answer: 
person = Person.new(name: 'bob', age: '18')
person.name   # => 'bob'
person.age    # => '18'
person.valid? # => true

7. Views-New helper methods<ref>http://blog.remarkablelabs.com/2012/12/collection-form-helpers-rails-4-countdown-to-2013</ref>

Collection_select is a form helper that returns a <select> element and <option> tags for a collection. This method is very convenient for a belongs_to association, especially when you have lots of options for the user to select from. Rails 4 adds two new helper methods collection_check_boxes [Used for has_many relationships] and collection_radio_buttons[Used for belongs_to relationships].

8. Match method

Match method is used to match a URL pattern to routes.Rails 4 dropped support for the match method. One will now have to specify which HTTP verb to respond to with the option :via or explicitly mention GET,POST,or any other HTTP verb to specify the actions.

Example:

# match 'new', to: 'episodes#new', via: [:get, :post]
get 'new', to: 'episodes#new'

9. Update action now responds to patch/put request<ref>http://weblog.rubyonrails.org/2012/2/26/edge-rails-patch-is-the-new-primary-http-method-for-updates/</ref>

HTTP method PUT means that you can create or replace a file at a particular location. When we are uploading a file, we are either creating a file or replacing an existing file at that location. If we want to update a value of an attribute in a model, we can’t send the request via PUT request. To update such values, we need to send a complete representation of the model according to HTTP semantics. PUT does not allow partial updates. The solution to this is that we define the attribute as a resource by itself. It is not always a good practice to send the complete representation of the model for every update. Also replaying a request should provide you the same resource, which was violated by creating children resources using nested attributes. Thus, PATCH was introduced. It allows partial updates and is the primary method used in Rails 4.0.

10. TurboLinks<ref>https://github.com/rails/turbolinks</ref>

This is a new feature in Rails 4.0. Turbolinks is a brand new piece of JavaScript that is integrated as part of Rails 4. It is similar to PJAX. When enabled on a site, Turbolinks will fetch a part of a page and replace the contents of the current page with a new page.In Turbolinks, the entire body of the page is replaced, whereas in pjax we need to specify the part of the page to be replaced. Turbolinks works by fetching the clicked link asynchronously and then replacing the entire contents of the document body with the new page. The benefit of this is that you save client side time by not having to re-check for existing css, javascript, and possibly even images. The layout of assets on your server would have to support this. More than likely, your application probably doesn’t need many changes to support this. In cases where it doesn’t, the asset pipeline makes it very easy to concatenate different assets.Behind the scenes, Turbolinks uses something called pushState to change the browser address. The address is replaced immediately with new information. In the case of Turbolinks, it will make the browser address mimic what it would normally be if you had clicked the link and had the normal page load process complete. Turbolinks can be taken advantage of anywhere internally, but for security reasons it will not fetch and replace with external site. Turbolinks can be added to the project by adding gem 'turbolinks' to your Gemfile.

Tubolinks, however, are not helpful in large websites with a lot of page content and PJAX is a better option.

11. Russian Doll Caching<ref>http://blog.remarkablelabs.com/2012/12/russian-doll-caching-cache-digests-rails-4-countdown-to-2013</ref>

The technique of nesting fragment caches to maximize cache hits is known as Russian Doll Caching. By nesting fragment caches, it ensures that caches can be reused even when content changes. When a change occurs to the top-most fragment cache, only that cache must be expired. Every nested cache of the parent can be reused, which provides a significant performance increase. A change to the most nested fragment cache would start a chain reaction to expire all parent caches.

Example:

We are going to have a Team model which has many Members. When we display a team, we must also render out member names.

class Team < ActiveRecord::Base
  has_many :members
end

class Member < ActiveRecord::Base
  belongs_to :team, touch: true
end

Adding the :touch option to belongs_to :team on the Member model, ensures that when a member is changed, we update the Team model as well. Breaking parent caches once children are modified is a primary concept of Russian Doll caching.

12. Action Controller live added<ref>http://blog.remarkablelabs.com/2012/12/live-streaming-rails-4-countdown-to-2013</ref>

One major feature that was added to Rails 4 was ability to stream data to the user. Templates can be streamed to the users in Rails V3 as well. But Rails 4 added support for other types of data like JSON etc. To use Live streaming, module ActionController::Live must be added. This provides an I/O like interface to the response, allowing you to continuously write to the client until the stream is explicitly closed. This new development now allows rails to do more than serving HTTP pages and JSON. It can now handle variety of use cases like server sent events, chat clients, push notifications, real time feeds which couldn't be done before. Here is an example of a live streaming controller from the Rails docs:

class MyController < ActionController::Base
  include ActionController::Live

  def stream
    response.headers['Content-Type'] = 'text/event-stream'
    100.times {
      response.stream.write "hello world\n"
      sleep 1
    }
    response.stream.close
  end
end

ActionController::Live requires that all actions executed from ActionController::Live enabled controllers run in a separate thread, a concurrent ruby server to take advantage of live streaming , headers to be written before anything else to the client and streams must be closed.

13. No more vendor plugins

Rails 4 removed support for Rails::Plugins class<ref>http://weblog.rubyonrails.org/2012/1/4/rails-3-2-0-rc2-has-been-released/ </ref>. Developers are now requested to use Bundler with path or git dependencies. Thus, any code in the Vendor/Plugin directory will not be loaded at all. If the application still has code in the vendor/plugin directory then a better option would be to move it to a gem or move it to lib/your_plugin and require it from an initializer on config/initializers


14. Thread-safe by Default<ref>http://www.sitepoint.com/config-threadsafe/</ref>

Threadsafe! option is enabled by default in production mode beginning rails 4 which is immensely helpful in multi threaded environment. Threadsafe controls 4 options of which @preload_frameworks,@cache_classes and @dependency_loading are largely already being used in multi process environment, It can be turned off by setting config.cache_classes and config.eager_load to false.

15. ActiveRecord Scopes Need A Callable object<ref>http://www.sitepoint.com/get-your-app-ready-for-rails-4/</ref>

The eager evaluation of scopes without a lambda has always been the reason of frustration of many Rails developers.

An example of this is time based conditions being eagerly-evaluated: In Rails 4, all ActiveRecord scopes must be defined with a callable object (like Proc or lambda):

Rails 3.2

scope :recent, where(created_at: Time.now - 2.weeks)

Thus,Any future call to the recent scope, would always be 2 weeks before its initial evaluation. Rails 4

scope :recent, -> { where("created_at > ?", Time.now - 2.weeks).order("created_at desc") }
scope :active, -> { where(status: 'active') }

This helps avoid subtle bugs with Date or Time objects that get evaluated once, instead of being dynamically evaluated. They are always evaluated at run time.

Further Reading

Rails 4 has been released Collection of Video Tutorials on Popular Rails Topics
Rails 4 Release Notes
What's New in Rails 4]
Ruby Forums

References:

<references/>