What’s coming to Rails 6.0?

What’s coming to Rails 6.

0?Guy MaliarBlockedUnblockFollowFollowingFeb 13Rails 6.

0 will be released soon and it’s packed with many features that both smaller and bigger applications will benefit from, as it feels like many improvements around speed and scalability were introduced in Rails 6.

I’ve read through the CHANGELOGs of all Rails parts (ActiveRecord, ActionPack, ActiveSupport, etc.

) and picked some of the features that I found the most interesting.

Two new additions to the Rails family are Action Mailbox and Action Text that come straight out of Basecamp.

Active RecordAdd basic API for connection switching to support multiple databasesConnection switching support has been on my list for a long time, I’ve used the Octopus gem a few times before as well, but it always felt a little bit clunky in my opinion.

Eileen M.

Uchitelle has extracted out of Github’s codebase and into Rails’ this amazing feature, a native solution to switch database connections for specific models and/or specific queries.

The code is available as part of the pull request, https://github.

com/rails/rails/pull/34052, it’s documented amazingly and very easy to follow through.

class AnimalsModel < ApplicationRecord self.

abstract_class = true connects_to database: { writing: :animals_primary, reading: :animals_replica }endclass Dog < AnimalsModel # connected to both the animals_primary db for writing and the animals_replica for readingendSlow queries in jobs can be read from a replica using a simple APIActiveRecord::Base.

connected_to(database: :slow_replica) do SlowReplicaModel.

firstendAnd the database.

yml file is simply a little bit longerdevelopment: primary: database: my_primary_db user: root primary_replica: database: my_primary_db user: ro_user replica: true animals: database: my_animals_db user: root animals_replica database: my_animals_db user: ro_user replica: trueGannon McGibbon later added some more amazing code supporting hash and url configs in database hash of ActiveRecord::Base.

connected_to which open up these possibilitiesUser.

connected_to(database: { writing: "postgres://foo" }) do User.

create!(name: "Gannon")endconfig = { "adapter" => "sqlite3", "database" => "db/readonly.

sqlite3" }User.

connected_to(database: { reading: config }) do User.

countendAdd Relation#pick as short-hand for single-value plucksJust as the name suggests pick can pluck single-valuesPerson.

where(id: 1).

pick(:name, :email_address)# SELECT people.

name, people.

email_address FROM people WHERE id = 1 LIMIT 1# => ['David', 'david@loudthinking.

com']Add ActiveRecord::Base.

create_or_find_by/!.to deal with the SELECT/INSERT race conditionA while back, DHH have started YouTube series called On Writing Software Well which later became part of the Getting Better YouTube page, on one of the videos he shows his technique for addressing the issues with find_or_create_by and the alternative create_or_find_by which relies on a database unique constraint.

The code itself is fairly intuitive and is taken directly from the Rails sourcecode.

def create_or_find_by(attributes, &block) transaction(requires_new: true) { create(attributes, &block) }rescue ActiveRecord::RecordNotUnique find_by!(attributes)endThere are several drawbacks to this solution which are stated and I suggest reading them before using this solution.

Make the implicit order column configurableFor applications that don’t use sequential IDs this one is golden.

When using UUIDs as default column identifier, first and last methods no longer make sense.

Now we will be able to set the order of the records with a single line of configuration.

class User < ActiveRecord::Base self.

implicit_order_column = "created_at"end Action MailboxAction Mailbox is introduced in the sixth version of Ruby on Rails, I’m sure many posts will be written about it in the near future and it’s pretty exciting.

Action Mailbox provides a set of tools that will allow applications to better integrate with inbound emails flows.

The basics are covered at Action Mailbox Basics Rails Guide but a few cool ideas would be conversations that happen automatically in both a platform and email and are interchangeable, think about Github comments from emails, help desk emails that turn into tickets or even GDPR delete requests.

Example mailbox for adding comments to a Post by emailThe documentation to set up Action Mailbox is available at https://edgeguides.

rubyonrails.

org/action_mailbox_basics.

html, it covers the required configuration of Action Mailbox available providers.

Pay attention that Action Mailbox requires Active Job and Active Storage as part of it’s and a database table.

Most of the class documentation is also available at ActionMailbox::Base class documentation, ActionMailbox::InboundEmail class documentation and working with a parsed email is done by using the Mail gem.

Action TextAction Text is an implementation of the new Trix editor by Basecamp bundled into ActiveRecord models.

It exposes a has_rich_text method that we can apply to models and Action Text will take care of the rest.

Action Text requires ActiveStorage and some database tables to persist it’s metadata, so be aware that you’d want to switch to an ActiveStorage provider that does not persist to disk if you’re working on applications that require more than one server.

The documentation is available at the Rails Guides and it’s pretty self-explanatory.

Action PackIntroduce ActionDispatch::HostAuthorizationHost Authorization is a new middleware that guards against DNS rebinding attacks by explicitly permitting the hosts a request can be sent to.

More information about the attack itself is available in this Medium post and in Daniel Miessler’s DNS Rebinding attack explained.

By default it’s set for all Rails 6 applications and allows in development the following hosts IPAddr.

new(“0.

0.

0.

0/0”), IPAddr.

new(“::/0”), “localhost”] it supports arrays of RegExp, Proc, IPAddr and String or a single String in the configuration.

What this means is that with Rails 6, we will need to explicitly set our domains in the environments configuration files.

More information is available at the HostAuthoriation code and HostAuthorization tests.

Purpose metadata for signed/encrypted cookiesRails can now thwart attacks that attempt to copy signed/encrypted value of a cookie and use it as the value of another cookie.

It does so by stashing the cookie-name in the purpose field which is then signed/encrypted along with the cookie value.

Then, on a server-side read, we verify the cookie-names and discard any attacked cookies.

Enable action_dispatch.

use_cookies_with_metadata to use this feature, which writes cookies with the new purpose and expiry metadata embedded.

Pass along arguments to underlying GET method in #follow_redirect!It’s possible to pass parameters to the underlying GET request in a follow_redirect!.by adding an additional arguments to the method.

def create # do stuff follow_redirect!(params: { user: params[:user_id] })endAction ViewAdd allocations to template rendering instrumentationAaron Patterson is on an ever-long performance optimization quest and his latest addition is allocations.

Rails 6 will report on allocations made in views, which will allow developers be aware of how much time is spent in allocating and garbage collecting objects in the process’ memory.

Rendered posts/_form.

html.

erb (Duration: 7.

1ms | Allocations: 6004) Rendered posts/new.

html.

erb within layouts/application (Duration: 8.

3ms | Allocations: 6654)Completed 200 OK in 858ms (Views: 848.

4ms | ActiveRecord: 0.

4ms | Allocations: 1539564)Active JobAdded enqueue_retry.

active_job, retry_stopped.

active_job, and discard.

active_job instrumentation hooksRails has a very extensive instrumentation hooks built into Active Support and it spans across the entire framework.

It allows subscribing on specific events that happen throughout the lifecycle of requests, SQL queries and jobs and report them for example to a Prometheus instance.

With the addition of enqueue_retry.

active_job , retry_stopped.

active_job and discard.

active_job it is easier to instrument based on jobs’ status.

Allow passing multiple exceptions to #retry_on and #discard_onIt’s now possible to retry on multiple exceptionsretry_on Errno::ECONNREFUSED, SocketError, Timeout::Error, attempts: 5Active ModelAllows configurable attribute name for #has_secure_passwordThis still defaults to an attribute named 'password', causing no breaking change.

There is a new method #authenticate_XXX where XXX is the configured attribute name, making the existing #authenticate now an alias for this when the attribute is the default 'password'.

class User < ActiveRecord::Base has_secure_password :recovery_password, validations: falseenduser = User.

new()user.

recovery_password = "42password"user.

recovery_password_digest # => "$2a$04$iOfhwahFymCs5weB3BNH/uX.

"user.

authenticate_recovery_password('42password') # => userActive StorageUploaded files assigned to a record are persisted to storage when the record is saved instead of immediatelyIn rails 5.

2 files were persisted immediately when assigned@user.

avatar = params[:avatar]Rather when @user.

save was called, the behavior now is as expectedUse the ImageProcessing gem for Active Storage variants, and deprecate the MiniMagick backendImageProcessing support some better macros such as :resize_to_fit, :resize_to_fill and also has built in libvips which is in an alternative to ImageMagick.

The change is also easily configurable using the usual Rails configurationRails.

application.

config.

active_storage.

variant_processor = :vipsAction CableMerge action-cable-testing into RailsThis is a pretty cool addition, it lets us test action cable interactions more easily.

Taken from action-cable-testing gem on GithubThe ActionCable javascript package has been converted from CoffeeScript to ES2015, and we now publish the source code in the npm distributionI personally prefer ES2015 javascript to Coffeescript so I think it’s great.

Action MailerAdd MailDeliveryJob for delivering both regular and parameterized mail, deprecate using DeliveryJob and Parameterized::DeliveryJobDeliveryJob and Parameterized::DeliveryJob are deprecated in favor of MailDeliveryJob it is used for sending emails outside of the request-response cycle.

Action SupportAdds parallel testing to RailsParallel testing was a little bit hard up until Rails 6 especially in CI systems when you needed isolation between processes and interference with the database.

I’ve written some weird database.

yml s that rely on an environment variable that creates multiple databases in each of the CI build.

Starting Rails 6 that would no longer be necessary as it is possible to just specify in Minitestclass ActiveSupport::TestCase parallelize(workers: 2, with: :processes) # or :threadsendor through environment variable PARALLEL_WORKERS and it’ll create the database with a numbered suffix.

More information is available in Bogdan’s What Is New In Rails 6.

0Add support for tracing constant autoloadsTracing constant autoloads is pretty easy now if you’re having trouble with autoloading constants on file changes.

Create an initializer called autoload_trace.

rb and add the following codeif Rails.

env.

development?.ActiveSupport::Dependencies.

logger = Rails.

logger ActiveSupport::Dependencies.

verbose = trueendAdd cpu_time, idle_time, and allocations to ActiveSupport::Notifications::EventActiveSupport::Notifications.

subscribe('wait') do |event| @event = eventendActiveSupport::Notifications.

instrument('wait') do sleep 1endp @event.

allocations # => 7p @event.

cpu_time # => 0.

256p @event.

idle_time # => 1003.

2399GeneralRails 6 requires Ruby 2.

5.

0 or newerIn order to upgrade to Rails 6 we must upgrade to Ruby 2.

5+, quite obvious.

.. More details

Leave a Reply