As you might have already heard, the latest stuff for upgrading rails was finally released at the end of the last year, viz. 4.2.0 was released on Dec 19, 2014. Well, here is the quick overview of its major tools:
Active Job
It is a common interface on top of queuing systems like Resque, Delayed Job, Sidekiq, etc.
Active Job is a framework for declaring jobs and making them run on a variety of queueing backends. These jobs can be everything from regularly scheduled clean-ups, to billing charges, to mailings; anything that can be separated into small units of work and run in parallel.
Also there could be other framework features and other gems built on top of that, without having to worry about API differences between Delayed Job and Resque.
Usage
Set the queue adapter for Active Job:
ActiveJob::Base.queue_adapter = :inline # default queue adapter
Declare a job like so:
classMyJob< ActiveJob::Base
queue_as :my_jobs
defperform(record)
record.do_work
end
end
Enqueue a job like so:
MyJob.perform_later record # Enqueue a job to be performed as soon the queueing system is free.
MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record) # Enqueue a job to be performed tomorrow at noon.
MyJob.set(wait: 1.week).perform_later(record) # Enqueue a job to be performed 1 week from now.
That's all.
GlobalID support
Active Job supports GlobalID serialization for parameters.
Tip:
A Global ID is a URI that uniquely identifies a model instance:
gid://YourApp/Some::Model/id
This is helpful when you need a single identifier to reference different classes of objects.
One example is job scheduling:
we need to reference a model object rather than serialize the object itself. We can pass a Global ID that can be used to locate the model when it's time to perform the job. The job scheduler doesn't need to know the details of model naming and IDs, just that it has a global identifier that references a model.
Another example:
a drop-down list of options, consisting of both Users and Groups. Normally we'd need to come up with our own ad hoc scheme to reference them. With Global IDs, we have a universal identifier that works for objects of both classes.
This makes it possible to pass live Active Record objects to your job instead of class / id pairs, which you then have to manually deserialize. Before, jobs would look like this:
classTrashableCleanupJob
defperform(trashable_class, trashable_id, depth)
trashable = trashable_class.constantize.find(trashable_id)
trashable.cleanup(depth)
end
end
Now you can simply do:
classTrashableCleanupJob
defperform(trashable, depth)
trashable.cleanup(depth)
end
end
Asynchronous Mails
Active Jobs also serves as the backend for Action Mailer's #deliver_later functionality that makes it easy to turn any mailing into a job for running later. That's one of the most common jobs in a modern web application: sending emails outside of the request-response cycle, so the user doesn't have to wait for it.
Sending emails right away is still possible with deliver_now.
Adequate Record
Adequate Record is a set of performance improvements in Active Record that makes find_by calls and some association queries up to 2x faster.
It works by caching common SQL queries as prepared statements and reusing them on similar calls, skipping most of the query-generation work on subsequent calls.
Active Record will automatically take advantage of this feature on supported operations without any user involvement or code changes. Here are some examples of supported operations:
Post.find(1) # First call generates and cache the prepared statement
Post.find(2) # Subsequent calls reuse the cached prepared statement
Post.find_by_title('first post')
Post.find_by_title('second post')
Post.find_by(title: 'first post')
Post.find_by(title: 'second post')
post.comments
post.comments(true)
It's important to highlight that, as the examples above suggest, the prepared statements do not cache the values passed in the method calls; rather, they have placeholders for them.
Web Console
New applications generated with Rails 4.2 now come with the Web Console gem by default.
Web Console is a set of debugging tools for your Rails application.
A debugging tool in the default error page.
An interactive console is launched automatically in the default Rails error page. It makes it easy to inspect the stack trace and execute Ruby code in the stack trace's bindings.
A debugging tool in your controllers and views.
Drop <%= console %> anywhere in a view to launch an interactive console session and execute code in it. Drop console anywhere in a controller and do the same in the context of the controller action.
Installation:
To install it in your current application, add the following to your Gemfile.
group :development do
gem 'web-console', '~> 2.0'
end
After you save the Gemfile changes, make sure to run bundle install and restart your server.
Configuration
It allows you to execute arbitrary code on the server, so you should be very careful; who you give access to it.
config.web_console.whitelisted_ips
By default, only requests coming from 127.0.0.1 are allowed.
config.web_console.whitelisted_ips lets you control which IP's have access to the console.
Let's say you want to share your console with 192.168.0.100. You can do this so:
classApplication< Rails::Application
config.web_console.whitelisted_ips = %w( 127.0.0.1 192.168.0.100 )
end
From the example, you can guess that config.web_console.whitelisted_ips accepts an array of ip addresses, provided as strings.
If you want to whitelist a whole network, you can do it like this:
classApplication< Rails::Application
config.web_console.whitelisted_ips = '192.168.0.0/16'
end
Again, note that this network doesn't allow 127.0.0.1. If you want to access the console, you have to do so from it's external IP or add 127.0.0.1 to the mix.
Foreign Key Support
The migration DSL now supports adding and removing foreign keys. At this time, only the mysql, mysql2 and postgresql adapters support foreign keys.
# add a foreign key to `articles.author_id` referencing `authors.id`
add_foreign_key :articles, :authors
# add a foreign key to `articles.author_id` referencing `users.lng_id`
add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id"
# remove the foreign key on `accounts.branch_id`
remove_foreign_key :accounts, :branches
# remove the foreign key on `accounts.owner_id`
remove_foreign_key :accounts, column: :owner_id
Incompatibilities
Previously, calling render "foo/bar" in a controller action was equivalent to render file: "foo/bar". In Rails 4.2, this has been changed to mean render template: "foo/bar" instead. If you need to render a file, please change your code to use the explicit form (render file: "foo/bar") instead.
respond_with and the corresponding class-level respond_to have been moved to the responders gem. Add gem 'responders', '~> 2.0' to your Gemfile to use it:
# app/controllers/users_controller.rb
classUsersController< ApplicationController
respond_to :html, :json
defshow
@user = User.find(params[:id])
respond_with @user
end
end
Instance-level respond_to is unaffected:
# app/controllers/users_controller.rb
classUsersController< ApplicationController
defshow
@user = User.find(params[:id])
respond_to do |format|
format.html
format.json { render json: @user }
end
end
end
Due to a change in Rack, rails server now listens on localhost instead of 0.0.0.0 by default. This should have minimal impact on the standard development workflow as both http://127.0.0.1:3000 and http://localhost:3000 will continue to work as before on your own machine.
The HTML sanitizer has been replaced with a new, more robust, implementation built upon Loofahand Nokogiri. The new sanitizer is more secure and its sanitization is more powerful and flexible.
Due to the new algorithm, the sanitized output may be different for certain pathological inputs.
If you have a particular need for the exact output of the old sanitizer, you can add the rails-deprecated_sanitizer gem to the Gemfile, to have the old behavior.
rails-deprecated_sanitizer will be supported for Rails 4.2 only; it will not be maintained for Rails 5.0.
assert_select is now based on Nokogiri. As a result, some previously-valid selectors are now unsupported. If your application is using any of these spellings, you will need to update them:
# before
a[href=/]
a[href$=/]
# now
a[href="/"]
a[href$="/"]
DOMs built from HTML source containing invalid HTML with improperly nested elements may differ. For example:
# content: <div><i><p></i></div>
# before:
assert_select('div > i') # => true
assert_select('div > p') # => false
assert_select('i > p') # => true
# now:
assert_select('div > i') # => true
assert_select('div > p') # => true
assert_select('i > p') # => false
If the data selected contains entities, the value selected for comparison used to be raw (e.g. AT&T), and now is evaluated (e.g. AT&T).
# content: <p>AT&T</p>
# before:
assert_select('p', 'AT&T') # => true
assert_select('p', 'AT&T') # => false
# now:
assert_select('p', 'AT&T') # => true
assert_select('p', 'AT&T') # => false
There are hundreds of posts on this topic. So please feel free to share others in the comments, to make this resource list longer and better.
Categories
Tags
Favourite posts
Getting an e-Commerce website online might sound like a huge undertaking,...
WebView displays web pages. But we are interested not only in web-content...
Google Maps is a very famous and helpful service, which firmly entrenched...
RSpec is an integral part of Test Drive Development (TDD) and its main id...
When developing a web application that extensively works with user input ...
Field configuration defines behavior of all standart (system) fields and ...
As you might have already heard, the latest stuff for upgrading rails was...