Rails 6.1 deprecatesrails db:structure:load and rails db:structure:dump tasks.
Before Rails 6.1, executing rake db:schema:dump would dump db/schema.rb file.
And executing rake db:structure:dump would dump db/structure.sql file.
Rails provides config.active_record.schema_format setting for which the valid values are :ruby or :sql.
However, since there are specific tasks for db:structure and db:schema this value was not really being used.
Changes in Rails 6.1
In Rails 6.1 the Rails team decided to combine the two different tasks into a single task.
In Rails 6.1 rails db:structure:dump and rails db:structure:load have been deprecated and the
following message would be shown.
Now Rails will start taking into the account value set for config.active_record.schema_format.
rails db:schema:dump and rails db:schema:load would do the right thing based on the value set for config.active_record.schema_format.
Rails 6 added
including and excluding
on Array and Enumerable.
Array#including and Enumerable#including
including can be used
to extend a collection
in a more
object oriented way.
It does not mutate
the original collection
a new collection
which is the
of the given collections.
Array#excluding and Enumerable#excluding
It returns a copy
of the enumerable
the given collection.
Array#excluding and Enumerable#excluding replaces
the already existing method
which in Rails 6 is now
aliased to excluding.
excluding and including helps
to shrink or extend
without using any operator.
Rails 6.1 adds support to handle db:rollback in case of multiple database application.
Prior to this change, on executing db:rollback Rails used to rollback the latest migration from the primary database. If we passed on a [:NAME] option along with to specify the database, we used to get an error.
Check out the issue for more details.
Staring with Rails 6.1, we need to pass the database name along with db:rollback:[NAME] otherwise a RuntimeError is raised.
If the template is
as simple as this one
then there are no issues.
we have a liquid template
which is using another liquid template.
Here is an example.
In the above case home.liquid is using two other liquid templates main.css and header.liquid.
Let’ see what these templates look like.
In order to include the assets and the partials
we need to create liquid tags.
Let’s create a tag which will handle assets.
Let’s create a tag that will handle partials.
Let’s create a new initializer and we need to register
these tags in that initializer.
Restart the server and now we can render the home.liquid template
Here we have
a simple implementation of
We can do much more, if needed, like
looping over items
to parse each item from the partial.
That can be done
by registering a separate tag for
the item and passing in
the id of the item so that
the specific item can be found and parsed.
from Rails 6.0.
To use a specific database,
we can specify the
in the model
In the following case we want Person model to connect to crm database.
As the application grows,
more and more
models start sharing
the same database.
Now a lot of models may
contain connects_to call
to the same database.
In order to avoid the
we can create an abstract class
connecting to a database
and manually inherit
all other models
from that class.
This could look like this.
Before Rails 6.1 we had no choice but to
create that abstract class manually.
Rails 6.1 allows us to generate an abstract class when we are generating a model using scaffold.
$ rails g scaffold Person name:string --database=crm
an abstract class
appended with Record.
The generated model
the new abstract class.
it is not
We can also
use an existing
class as the abstract class
parent option to
the scaffold command.
$ rails g scaffold Customer name:string --database=crm --parent=PrimaryRecord
generating CrmRecord class
as we have
PrimaryRecord abstract class
as its parent.
Rails 6.1 makes it easier
to configure a default value
for Active Record enum attributes.
Let’s take an example of
blog posts with status and
Before Rails 6.1,
defaults for enum attributes
can be configured by applying
default on the database level.
After Rails 6.1,
defaults for enum attributes
can be configured directly
in the Post model using
The new approach to set enum defaults has following
advantages. Let’s understand keeping the context of
Post model with category as an example.
When the category default value changes from
Rails to React. We have to add a
new migration in Rails 6 and previous versions
to update the database column default.
Let say the default value for post category(i.e: Rails)
is removed from the enum from Post model.
Rails 6 and previous versions
wouldn’t throw an exception and continue
to work without setting any default
value. Rails 6.1 with new syntax would raise
Active Storage variants are
the transformation of the original
image. These variants can be used
as thumbnails, avatars, etc.
Active Storage generates variants
on demand by downloading the original
image. The image is transformed into a
variant and is stored to the third party
services like S3.
When a request to fetch a
variant for an Active Storage object
is made, Rails checks if the variant is already
been processed and is already available
on S3 or not. But to do so Rails
has to make a call to find out if the variant
is available on S3. This extra call
adds to the latency.
Active Storage has to wait until the
image variant check call is completed because
S3 might not return the image when a
GET request is made due to eventual
This way Rails avoid downloading a broken
image from S3 and uploading broken image variant
to S3 in case the variant is not present.
In Rails 6.1,
Active Storage tracks the presence
of the variant in the database.
This change avoids unnecessary
variant presence remote request
made to the S3 and directly
fetches or generates a image
In Rails 6.1,
the configuration to allow
variant tracking in the database is
by default set to true.
A notable change has been announced for Ruby 3
for which deprecation warning has been added
in Ruby 2.7.
Ruby 2.7 deprecated
automatic conversion of
keyword arguments and
This conversion will be completely removed
in Ruby 3.
Ruby 2.7 NEWS has listed
the spec of keyword arguments for Ruby 3.0.
We will take the examples mentioned there and
for each scenario we will look into
how we can fix them in the existing codebase.
When method definition accepts
keyword arguments as the last argument.
Passing exact keyword arguments
in a method call is acceptable,
but in applications we usually
pass a hash to a method call.
In this case,
we can add a double splat operator to the hash
to avoid deprecation warning.
When method call passes keyword arguments
but does not pass enough required
If the number of positional arguments doesn’t
match with method definition, then
keyword arguments passed
in method call will be
considered as the last positional argument
to the method.
To avoid deprecation warning
and for code to be compatible with Ruby 3,
we should pass hash instead of
keyword arguments in method call.
When a method accepts a hash and keyword arguments but
method call passes only hash or keyword arguments.
If a method arguments are a mix of symbol keys and non-symbol keys,
and the method definition accepts either one of them
then Ruby splits the keyword arguments
but also raises a warning.
To fix this warning,
we should pass hash separately
as defined in the method definition.
When an empty hash with double splat operator is passed
to a method that doesn’t accept keyword arguments.
Passing keyword arguments using double splat operator
to a method
that doesn’t accept keyword argument
will send empty hash similar to earlier version of Ruby
but will raise a warning.
To avoid this warning,
we should change method call to pass hash instead of
using double splat operator.
Added support for non-symbol keys
In Ruby 2.6.0, support for non-symbol keys
in method call
It is added back in Ruby 2.7.
When method accepts arbitrary keyword arguments
using double splat operator then non-symbol keys
can also be passed.
Added support for **nil
Ruby 2.7 added support for **nil
to explicitly mention if a method doesn’t
accept any keyword arguments in method call.
Ruby 2.0 introduced Enumerator::Lazy,
a special type of enumerator which helps us in processing chains of operations on a collection
without actually executing it instantly.
By applying Enumerable#lazy
method on any enumerable object, we can convert that object into Enumerator::Lazy object.
The chains of actions on this lazy enumerator will be evaluated only when it is needed.
It helps us in processing operations on large collections, files and infinite sequences seamlessly.
When we chain more operations on Enumerable#lazy object, it again returns lazy object
without executing it. So, when we pass lazy objects to any method which expects a normal
enumerable object as an argument, we have to force evaluation on lazy object by calling
to_a method or it’s alias
method returns a normal enumerator from a lazy enumerator, so that lazy enumerator object can
be passed to any methods which expects a normal enumerable object as an argument.
Also, we can call other usual array methods on the collection to get desired results.
The same way, we can use eager method when we pass lazy enumerator as an argument to
any method which expects a normal enumerator.
At some point, all of us have used names like a, n, i etc
for block parameters.
Below are few examples where
numbered parameters can come in handy.
Ruby 2.7 introduces a new way to access block parameters.
Ruby 2.7 onwards, if block parameters are obvious and
we wish to not use absurd names like n or i etc,
we can use numbered parameters which are available
inside a block by default.
We can use _1 for first parameter,
_2 for second parameter and so on.
Here’s how Ruby 2.7 provides numbered parameters inside a block.
Below shown are the examples from above,
only this time using numbered parameters.
Like mentioned in
Ruby now raises a warning if we try to
define local variable in the format _1.
Local variable will have precedence over
numbered parameter inside the block.
Numbered parameters are not accessible inside the block
if we define ordinary parameters.
If we try to access _1 when ordinary parameters are
defined, then ruby raises SyntaxError like shown below.
This feature was suggested 9 years back
and came back in discussion last year.
After many suggestions community agreed to use _1 syntax.
Let’s say that we have to
find the frequency of
each element of an array.
Before Ruby 2.7,
we could have achieved it
using group_by or inject.
Ruby 2.7 adds Enumerable#tally
which can be used
to find the frequency.
Tally makes the code
more readable and intuitive.
It returns a hash
where keys are the unique elements
and values are its corresponding