In Rails 6.1, Rails will skip modifications to the test database
if SKIP_TEST_DATABASE is set to true.
Without the environment variable
With the environment variable
As we can see in the first example, both a development and a test database were created, which is unexpected when directly invoking db:create.
One obvious solution to this problem is to force the development environment to only create a development database.
However this solution will break bin/setup as mentioned in this commit.
Hence the need for an environment variable to skip test database creation.
Before Rails 6.1, batch processing methods like find_each, find_in_batches and in_batches didn’t support the ORDER BY clause. By default the order was set to id ASC.
Rails 6.1 now supports ORDER BY id for ActiveRecord batch processing methods like find_each, find_in_batches, and in_batches. This would allow us to retrieve the records in ascending or descending order of ID.
Points to remember:
The ORDER BY clause only works with the primary key column.
Valid values for the ORDER BY clause are [:asc,:desc] and it’s case sensitive. If we use caps or title case (like DESC or Asc) then we’ll get an ArgumentError as shown below.
All are excited about
what Ruby 3.0 has
to offer to the Ruby developers.
There is already a lot of buzz
that the feature set of Ruby 3.0
will change the perspective of developers
how they look at Ruby.
One of the important aspects of Ruby 3.0 is optimization.
The part of that optimization is
the introduction of name method for Symbol.
In this blog,
we will take a look
at what name method of class Symbol does
why it was introduced.
The new name method is introduced on Symbol
to simply convert a symbol into a string.
Symbol#name returns a string.
Let’s see how it works.
Don’t we have to_s
to convert a symbol into a string.
Most of us have used to_s method on a Symbol.
The to_s method returns a String object
we can simply use it.
But why name?
Using to_s is okay in most cases.
But the problem with to_s is
that it creates a new String object
everytime we call it on a symbol.
We can verify this in irb.
Creating a new object for every symbol to a string conversion
allocates new memory which increases overhead.
The light was thrown on this issue by
schneems (Richard Schneeman)
in a talk at RubyConf Thailand
where he showed how Symbol#to_s allocation
causes significant overhead in ActiveRecord.
This inspired Ruby community
to have a new method name on Symbol
which returns a frozen string object.
This reduces the string allocations dramatically
which results in reducing overhead.
to bring this feature was
that most of the times
we want a simple string representation
for displaying purpose
to interpolate into another string.
The result of to_s is rarely mutated directly.
By introducing this method
we save a lot of objects
which helps in optimization.
Now we know the benefits of name,
we should prefer using name over to_s
when we don’t want to mutate a string.
To demonstrate one of the issues let’s take an example of a select dropdown.
CountryDropDown in the below example is a React component for country selection,
which would be rendered to a div with id react-root.
The react DOM container is wrapped inside a div with id main that has a change event containing stopPropagation().
Attaching change event to the main div
When a country is selected, we cannot see the selected country. Watch
to see it in action.
The reason for this unexpected behavior is the onChange event of dropdown
which is attached to the document node.
The change event of the main div containing e.stopPropagation() prevents
the onChange event of dropdown.
To fix such issues, React 17 no longer attaches event handlers at the document level.
Instead, it attaches them to the root DOM container into which React tree is rendered.
After changes in React 17, events are attached to the root DOM container into which the React tree is rendered.
In our example, onChange event of dropdown would be attached to the div with id react-root.
This event would be triggered when any country is selected rendering the expected behavior.
To see the solution in action, check out the
React 17 release candidate can be installed from
Check out the earlier discussion on event delegation
and the pull request
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.