CSC/ECE 517 Fall 2014/ch1a 21 as: Difference between revisions
No edit summary |
|||
Line 253: | Line 253: | ||
== References: == | == References: == | ||
<reference /> | |||
Revision as of 01:48, 18 September 2014
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 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 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
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.
Rails 3 Syntax
>>a => [42, 8, 17] >> a.sort => [8, 17, 42] >> a => [42, 8, 17]
Rails 4 Syntax
>> a => [42, 8, 17] >> a.sort! => [8, 17, 42] >> a => [8, 17, 42]
3. Article.find_by
In Rails 3.0, we could use a column name to search which relied on method missing. In Rails 4, use hash 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 :
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'
4. Strong Parameters
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:
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.
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.
6. Concerns Directory
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.service obj are better(?)
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
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
8. Views-New helper methods
collection_check_boxes/radio buttons
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]
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.
10. Update action now responds to patch/put request
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 whttp://wiki.expertiza.ncsu.edu/skins/common/images/button_bold.pnge 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.
11. TurboLinks
This is a new feature in Rails 4.0. 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. 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 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.
Tubolinks, however, are not helpful in large websites with a lot of page content and PJAX is a better option.
12. Russian Doll Caching
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.
13. Action Controller live added
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. 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 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.
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
15. Thread-safe by Default
Threadsafe! option is 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
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.
References:
<reference />