CSC/ECE 517 Fall 2014/ch1a 21 as: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
(Created page with "== Introduction == 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 eng...")
 
 
(43 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Introduction ==
=Differences between Rails 3 and Rails 4=
== Introduction<ref>http://en.wikipedia.org/wiki/Ruby_on_Rails</ref> ==


[http://en.wikipedia.org/wiki/Ruby_on_Rails Ruby on rails], or simply Rails, is a popular open source cross platform web application framework written in [http://en.wikipedia.org/wiki/Ruby_(programming_language) Ruby]. Rails follows many well-known software engineering patterns and paradigms including [http://en.wikipedia.org/wiki/Convention_over_configuration Configuration over Convention], [http://en.wikipedia.org/wiki/Don't_repeat_yourself Don't Repeat Yourself], [http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller Model View Controller], Active record pattern.


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 CoC, DRY, MVC, 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 [http://en.wikipedia.org/wiki/CoffeeScript CoffeeScript] and [http://en.wikipedia.org/wiki/Software_as_a_service 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 ==




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


David Heinemeier Hansson created RoR from his work at basecamp in 2003.It started receiving major attention after Apple decided that it will ship RoR 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.
Out of all the databases that are supported in [http://guides.rubyonrails.org/active_record_basics.html ActiveRecord], [https://wiki.postgresql.org/wiki/Main_Page 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.




== Changes from Rails 3 to Rails 4 ==
1. Native data types in postgres-
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. Mutate the current relation object--In Rails 3, a variable was assigned to mutated string while the original remained the same. In 4,! (Bang method) can be used which will change the original object itself. This helps in uncluttering the code.
In Rails 3,
>>a
=> [42, 8, 17]
>> a.sort
=> [8, 17, 42]
>> a
=> [42, 8, 17]


In Rails 4,
===2. Article.find_by<ref>http://blog.remarkablelabs.com/2012/12/what-s-new-in-active-record-rails-4-countdown-to-2013</ref>===
>> a
=> [42, 8, 17]
>> a.sort!
=> [8, 17, 42]
>> a
=> [8, 17, 42]


3. Article.find_by in 3- we could use a column name to search which relied on method missing. In 4, use hash
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.
Active Record, in previous versions of Rails, provided a finder method for every column in the table. For eg, 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 :
Examples :
Rails 3: Team.find_all_by_name('Justice League')
<pre>
Rails 4: Team.where(name: 'Justice League')
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 3: Team.find_or_create_by_name('Justice League')  
Rails 4: Team.where(name: 'Justice League').first_or_create
Rails 4: Team.where(name: 'Justice League').first_or_create  
</pre>


methods find_by and find_by! have been added to Rails 4.
methods find_by and find_by! have been added to Rails 4.<br>
Member.find_by name: 'Batman', city: 'Gotham'
 
Member.find_by! name: 'Superman'
<pre>Member.find_by name: 'Batman', city: 'Gotham'  
Member.find_by! name: 'Superman'  
</pre>
 
===3. Strong Parameters===
   
   
[NEEDS CORRECTION, ONLY MULTI PARAMETER FIND_BY ARE DEPRECATED]
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, [http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html Strong parameters] allow higher control over the content.
-
4. Strong params-better than attr-accessor epi 371 http://blog.sensible.io/2013/08/17/strong-parameters-by-example.html
A primary feature of Rails has always been the ability to sanitize user input coming from ubiquitous forms. However, till Rails3, accessible fields had to be listed in the models. In Rails 4, Strong parameters allow higher control over the content.
Example:
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.
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.<br><br>
 
<pre>
params = ActionController::Parameters.new(username: "john")
params = ActionController::Parameters.new(username: "john")  
User.new(params)
User.new(params)  
# => ActiveModel::ForbiddenAttributesError
# => ActiveModel::ForbiddenAttributesError
THe attributes which are required in mass assignment can be whitelisted to get rid of the error.
</pre>
params = ActionController::Parameters.new(username: "john")
The attributes which are required in mass assignment can be whitelisted to get rid of the error.  
> User.new(params.permit(:username))
<pre>params = ActionController::Parameters.new(username: "john")  
> User.new(params.permit(:username))  
</pre>


Whitelisting each and every parameter is not mandatory. However, not enlisting one will generate the forbidden attributes error.
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.
When using permit, if the permitted attribute is missing, it won’t throw any error.
<br>
<pre>params = ActionController::Parameters.new(username: "john", password: "secret")
params.permit(:username, :password, :foobar)
# => { "username" => "john", "password" => "secret" }
</pre>
If a parameter has to be present, Require command instead of permit is used.
<pre>
params.require(:foobar)
# ActionController::ParameterMissing: param not found: foobar
</pre>
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 [http://api.rubyonrails.org/v3.2.13/classes/ActiveRecord/SessionStore/Session.html ACTIVERECORD::SESSIONSTORE]. This functionality can still be achieved with the help of a gem by using 'activerecord-session_store' gem.


params = ActionController::Parameters.new(username: "john", password: "secret")
===5. Concerns Directory<ref>http://www.sitepoint.com/get-your-app-ready-for-rails-4/</ref>===
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)
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 [http://en.wikipedia.org/wiki/Don%27t_repeat_yourself DRY].
# 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.
Rails 3.2
5. ACTIVERECORD::SESSIONSTORE-Storing sessions in a database may be useful in certain application but is not as efficient as cookies.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.
<pre>
resources :messages  do
  resources :comments 
  post :trash, :restore, on: :member 
end 
resources :documents do 
  resources :comments 
  post :trash, :restore, on: :member 
end 
</pre>


6. Concerns directory-
Rails 4  
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.
<pre>
#Rails 3.2
concern :commentable do  
resources :messages do
   resources :comments   
   resources :comments
end   
  post :trash, :restore, on: :member
end
  resources :documents do
  resources :comments
  post :trash, :restore, on: :member
end
  #Rails 4
   
   
concern :commentable do
concern :trashable do
   resources :comments
   post :trash, :restore, on: :member 
end
end  
   
   
concern :trashable do
resources :messages, :documents, concerns: [:commentable, :trashable]  
  post :trash, :restore, on: :member
</pre>
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.  
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.service obj are better(?)
Thus, Concerns help to reduce large models.
7. Active model-Till 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


===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 [http://guides.rubyonrails.org/action_view_overview.html 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
<pre>
class Person
class Person
   include ActiveModel::Model
   include ActiveModel::Model
Line 107: Line 110:
   validates_presence_of :name
   validates_presence_of :name
end
end
 
Answer:
person = Person.new(name: 'bob', age: '18')
person = Person.new(name: 'bob', age: '18')
person.name  # => 'bob'
person.name  # => 'bob'
Line 113: Line 116:
person.valid? # => true
person.valid? # => true


https://github.com/rails/rails/tree/master/activemodel
</pre>


8. Views new helper methods--collection_check_boxes/radio buttons--many2many association
===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]


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].


http://blog.remarkablelabs.com/2012/12/collection-form-helpers-rails-4-countdown-to-2013
===8. Match method===


9. Match method--Rails 4 will drop 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.
Match method is used to match a URL pattern to routes.Rails 4 dropped support for the [http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper.html 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.


10. Update action now responds to patch/put request
Example:
The HTTP method PUT means resource creation or replacement at some given URL. Thus, Put method is always used for a complete update. When updating a resource in Rails, most often than not it is a partial update. PATCH is a method that is not safe, nor idempotent, and allows full and partial updates and side-effects on other resources. Thus, Patch was added as the primary method for updates in Rails 4.
<pre>
// 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.
# match 'new', to: 'episodes#new', via: [:get, :post]
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.
get 'new', to: 'episodes#new'
The solution to this is that we define the attribute as a resource by itself.
</pre>
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.


http://weblog.rubyonrails.org/2012/2/26/edge-rails-patch-is-the-new-primary-http-method-for-updates/
===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://blog.remarkablelabs.com/2012/12/http-patch-verb-rails-4-countdown-to-2013
http://weblog.rubyonrails.org/2012/2/26/edge-rails-patch-is-the-new-primary-http-method-for-updates/


11. TurboLinks
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.
New feature in 4.
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.
http://geekmonkey.org/articles/28-introducing-turbolinks-for-rails-4-0
 
https://github.com/rails/turbolinks
===10. TurboLinks<ref>https://github.com/rails/turbolinks</ref>===
http://blog.teamtreehouse.com/rails-4-a-look-at-turbolinks
 
Turbolinks is a brand new piece of JavaScript that is going to be 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.  
This is a new feature in Rails 4.0.
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 is a brand new piece of JavaScript that is integrated as part of Rails 4. It is similar to [http://railscasts.com/episodes/294-playing-with-pjax 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 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 your different assets. While you’re at it, add in some CSS spriting for fun and profit.
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.
Turbolinks can be added to the project by adding gem 'turbolinks' to your Gemfile.


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


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


http://blog.remarkablelabs.com/2012/12/russian-doll-caching-cache-digests-rails-4-countdown-to-2013
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.


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:


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.
We are going to have a Team model which has many Members. When we display a team, we must also render out member names.
 
<pre>
class Team < ActiveRecord::Base
class Team < ActiveRecord::Base
   has_many :members
   has_many :members
Line 167: Line 161:
   belongs_to :team, touch: true
   belongs_to :team, touch: true
end
end
 
</pre>
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.
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>===


13. Action controller live added
http://blog.remarkablelabs.com/2012/12/live-streaming-rails-4-countdown-to-2013


One major 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.
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 [http://edgeapi.rubyonrails.org/classes/ActionController/Live.html 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.
This new development now allows rails to do more than serving HTTP pages and [http://en.wikipedia.org/wiki/JSON 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:
Here is an example of a live streaming controller from the Rails docs:
 
<pre>
class MyController < ActionController::Base
class MyController < ActionController::Base
   include ActionController::Live
   include ActionController::Live
Line 190: Line 183:
   end
   end
end
end
ActionController::Live requires that a) all actions executed from ActionController::Live enables controllers run in a separate thread,b) a concurrent ruby server to take advantage of live streaming.c) headers to be written before anything else to the client d) Streams must be closed.
</pre>
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.


14. No more vendor plugins-Developers are now requested to use Bundler with path or git dependencies. Rails 4 removed support for Rails::plugins class. 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
===13. No more vendor plugins===


15. Thread-safe by Default
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 [http://railscasts.com/episodes/201-bundler Bundler] with path or [http://en.wikipedia.org/wiki/Git_(software) 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 [http://en.wikipedia.org/wiki/RubyGems gem] or move it to lib/your_plugin and require it from an initializer on config/initializers
Threadsafe! option will be enabled by default in production mode beginning rails 4.It can be turned off by setting config.cache_classes and config.eager_load to false.




16. ActiveRecord Scopes Need A Callable object
===14. Thread-safe by Default<ref>http://www.sitepoint.com/config-threadsafe/</ref>===
 
[http://blog.remarkablelabs.com/2012/12/rails-4-is-thread-safe-by-default-rails-4-countdown-to-2013 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.
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:
 
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):
In Rails 4, all ActiveRecord scopes must be defined with a callable object (like Proc or lambda):


#Rails 3.2
Rails 3.2
<pre>
scope :recent, where(created_at: Time.now - 2.weeks)
scope :recent, where(created_at: Time.now - 2.weeks)
</pre>
Thus,Any future call to the recent scope, would always be 2 weeks before its initial evaluation.
Thus,Any future call to the recent scope, would always be 2 weeks before its initial evaluation.
#Rails 4
Rails 4
<pre>
scope :recent, -> { where("created_at > ?", Time.now - 2.weeks).order("created_at desc") }
scope :recent, -> { where("created_at > ?", Time.now - 2.weeks).order("created_at desc") }
scope :active, -> { where(status: 'active') }
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 runtime.
</pre>
 
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==
 
[http://weblog.rubyonrails.org/2013/6/25/Rails-4-0-final/ Rails 4 has been released]
[http://railscasts.com/ Collection of Video Tutorials on Popular Rails Topics]<br>
[http://edgeguides.rubyonrails.org/4_0_release_notes.html Rails 4 Release Notes]<br>
[http://www.slideshare.net/silviorelli/whats-new-in-ruby-on-rails-4 What's New in Rails 4]]<br>
[https://www.ruby-forum.com/ Ruby Forums]<br>
== References: ==
== References: ==


1.https://www.railstutorial.org/book
<references/>
 
2.http://api.rubyonrails.org/classes/ActiveModel/Model.html
 
3.http://blog.remarkablelabs.com/2012/12/what-s-new-in-active-record-rails-4-countdown-to-2013
 
4.http://www.sitepoint.com/get-your-app-ready-for-rails-4/
 
5.http://blog.remarkablelabs.com/2012/12/a-love-affair-with-postgresql-rails-4-countdown-to-2013
 
6.Rails 3.0 is ready http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done/
 
7.Rails 3.0 release notes http://edgeguides.rubyonrails.org/3_0_release_notes.html
 
8.Rails 4.0 release notes http://edgeguides.rubyonrails.org/4_0_release_notes.html
 
9.https://github.com/rails/turbolinks
 
10.http://blog.teamtreehouse.com/rails-4-a-look-at-turbolinks

Latest revision as of 21:19, 25 September 2014

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/>