Recently we worked with a client where we had to run a part of their multi-threaded code in JRuby for performance reasons. They have been using CircleCI with MRI for running tests. In this post I will explain how we configured CircleCI to run the same tests using both JRuby and MRI.
CircleCI uses circle.yml file for configuration. Before configuring JRuby, this is how it looked like:
Here are the steps to enable JRuby in CircleCI.
Specify the JDK version
We need to specify a JDK version before using JRuby.
Install proper dependencies
We needed to use JRuby 184.108.40.206 but the version of JRuby that came with Ubuntu 12.04 image of CircleCI was different. We added rvm install command as follows to install specific version that we wanted. Also we can configure any script (like bundle install) that needs to run before running tests.
We used rvm-exec to set JRuby for running tests for this particular component in the test section. Otherwise by default it picks up MRI.
Improving test runs on JRuby
Once we started running tests with JRuby, we observed it was taking comparatively slower to finish all tests. Most of the time was spent in starting the JVM. We made it faster by setting --dev parameter in JRUBY_OPTS environment variable. This parameter improves JRuby boot time and it shaved more than a minute time for us.
in a React Native application allows
us to reuse already built web pages.
HTTP Headers are name/value pairs that
appear in both request and
The purpose of headers is to supply
the web server with additional information
and control how content is returned.
In React Native, while opening
web pages via WebView Component,
we can pass headers to the HTTP request.
Refer to our
for more on this.
But there is a bug.
On subsequent requests from
inside the WebView,
the headers are not passed in the request.
First, let’s try to understand
by recreating the bug.
We have created a simple node server
which will act as the backend
for the application and log the request
along with the custom header.
Here is our server.js
As we can see, the welcome page
has a link to bye and vice versa.
Let’s start the node server by running
When we run the app on the simulator,
the welcome page opens up,
and in the server log,
we can verify that the request
header is being passed.
But when we click on the Bye
link from the Welcome page,
the server doesn’t receive the
which can be verified from the log.
And it can be verified again
that for any subsequent clicks
the request header does
not get passed. We can click on
Welcome and check the log again.
We recently encountered this
bug and created an issue
Untill the issue is fixed,
we have found a workaround.
WebView provides a prop onLoadStart
which accepts a function that is
invoked when the WebView
We can use this prop to know
when a link is clicked
and then re-render the WebView
component with the new url.
Re-rendering the WebView component
will load the page as if it’s the
first page and then the request
headers would be passed.
We know that in React,
a component re-renders itself when
any of its state changes.
The only thing which changes
here is the url, so let’s move the
url to a state and
initialize it to the Welcome page
which is the root of the application.
And then use the onLoadStart prop
to change the url state to the clicked url.
Here’s the new code.
Now when we run the app,
we can verify in the backend that
the request headers are being sent
even when we click on Bye link.
One thing to note here is that,
when we click on the Bye link,
the request is not intercepted
from reaching the server.
We are just resending the
request by means of a component
re-render with the new url.
Hence in the log, we see two requests.
First request took place when
user clicked on the link,
and the second request occurred
when the component got re-rendered
with the required request headers.
This workaround might help us
to pass the request headers which
we intend to send to the backend
server until the issue gets fixed.
We are all guilty of treating ActionController::Parameters
as a plain hash at some point or the other.
But with Rails 5, ActionController::Parameters will no longer inherit
Inheriting from HashWithIndifferentAccess allowed programmers
to call enumerable methods over ActionController::Parameters,
which caused ActionController::Parameters to lose its @permitted state
there by rendering Strong Parameters as a barebone Hash.
would discourage such operations.
However since this change would have meant a major impact
on all of the upgrading applications as they would have crashed
with a NoMethodErrorfor all of those undesired methods.
Hence this feature would go through a deprecation cycle,
showing deprecation warnings for all of those
If you need to convert
in a true hash then it supports to_h method.
will continue to have methods like
fetch, slice, slice!, except, except!, extract!, delete etc.
You can take a detailed look at them
As we can see user_id has conflict in both
projection and GROUP BY as they are not prepended with the table name posts
in the generated SQL and thus, raising SQL error Column 'user_id' in field list is ambiguous.
Let’s assume that in our health care application
we have a page which shows all Patients.
also has a filter
it allows us to filter patients by their name.
We could implement the filter as shown here.
There might be many
users with the same name.
In such cases,
to speed up the search process,
we can add an index.
adding a regular index
will not trigger an index scan
we are using an expression
in the where clause i.e lower(name).
In such cases,
we can leverage
expression indexes given by PostgreSQL.
Before Rails 5
adding an expression index
is not straightforward
the migrate api does not support it.
In order to
we would need to ditch
schema.rb and start using
We would also need to add following migration.
Rails 4.2 came with built-in support for executing jobs
in the background
using Active Job.
Along with many enhancements to Active Job,
Rails 5 provides
the ability to attach arbitrary metadata to any job.
Consider the scenario where
we would like to get notified
when a job has failed for more than three times.
With the new enhancement,
we can make it work by
overriding serialize and deserialize methods
of the job class.
deserialization was performed by #deserialize class method
and therefore was inaccessible from the job instance.
With the new changes,
deserialization is delegated to the deserialize method on job instance
thereby allowing it to attach arbitrary metadata
when it gets serialized
and read it back
when it gets performed.
Before Rails 5, partials name should start with underscore
should be followed by any combination of letters, numbers
This rule was required because before
rendering a partial without giving :object or :collection used to generate
a local variable with the partial name by default and
a variable name in ruby can’t have dash and other things like that.
In the following case we have a file named _order-details.html.erb.
Now let’s try to use this partial.
We will get following error, if we try to render above view in Rails 4.x.
In the above the code failed because the partial name has a dash which
is not a valid ruby variable name.
in a React Native application
allows us to reuse already built web pages.
We have seen that in most of the “web view” based applications the links
in header are mostly turned in native navigational components.
It means server should not be sending header if React Native component
is asking for web pages.
However those headers should be present if the
request is not coming from the React Native app.
Passing custom request headers
We can configure React Native app to pass custom request headers
when request is made to the server to fetch pages.
While invoking WebView component we can pass customHeaders
as shown below.
Passing user agent
React Native also allows us to pass “userAgent” as a prop.
However it is only supported by android version of React Native.
For iOS, we would need to add the following lines to our
AppDelegate.m to set the userAgent.
This comments out requiring action_mailer/railtie
It also omits mailer specific configurations
such as config.action_mailer.raise_delivery_errors and
config.action_mailer.perform_caching in production/development
and config.action_mailer.delivery_method by default
in test environment.
As, we can see action_mailer/railtie is commented out.
The security threat we had was that
it was possible for an attacker to issue
unexpected database queries with “IS NULL” where clauses.
Though there was no threat of an insert being carried out,
there could be scope for firing queries that would check for NULL
even if it wasn’t intended.
In later version of Rails(> 3.2), we had a different way of handling
blank arrays in Active Record find_by and where clauses.
As you can see a conditional for empty array
doesn’t trigger IS NULL query, which solved part of the problem.
We still had conversion of empty array to nil
in the deep munging in place and hence there was still
a threat of undesired behavior when request contained
One way to handle it was to add before_action hooks
to the action that could modify the value to empty array
if it were nil.
Let’s see what happens with the POST request without specifying the response.
Rails happily returns with 204: No content response in this case.
This means users get the feel that nothing happened in the browser. Because Rails
returned with no content and browser happily accepted it.
But in reality, the user record was created in the database.
what happens with the GET request
in Rails 5.
Instead of 204: No Content, we get ActionController::UnknownFormat exception.
Rails is being extra smart here and hinting that we are probably missing
corresponding template for this controller action. It is smart enough to show us
this message as we requested this page via browser via a GET request.
But if the same request is made
via Ajax or through an API call or a POST request, Rails will return 204: No Content response as seen before.
In general, this change can trip us in the development phase, as we are used
to incremental steps like adding a route, then the controller action and then
the template or response. Getting 204 response can give a feel of nothing happening
where things have actually happened in the background. So don’t forget to respond properly
from your controller actions.