Redis cache store expiry, faster record instantation and more!

Hey there, detective! Here’s Kasper fumbling through his own trenchcoat for his notebook to give you what went down on the Rails codebase this week.

Redis cache store: increment/decrement expiry

If you’ve been looking to expire a key, either when incrementing or decrementing it, with Rails 5.2s Redis cache store. Just pass _expires_in _to make the key sleep with the fishes.

Guides digging almost too deep

The Rails guides are vast and deep. There’s so many that the digging deeper section almost dug its own grave. But splitting out into another section is a saving grace. Why not look through the current guides?

has_secure_password takes an attribute

For many years has_secure_password only allowed a default password attribute. But now you can stash whatever you want in there.

Reduce record instantiation allocations

Instantiating a list of Active Record objects is now faster and allocates less. If the array has the same instances that is. It’s made possible by not looking up the same STI column each time through the loop. 

OS X ditched for macOS

In lighter documentation news the old Mac OS X spelling has been replaced by macOS where applicable.

Multiple exceptions for retry_on/discard_on

Rails 5.1s syntactic sugar for retry_job, retry_on and discard_on that is, only took one exception so you’d have to duplicate exception blocks or spread a retry on multiple lines. No longer! Get your high in a single line of sugar.

20 people contributed to Rails this past week. There might be some open issues you can try tackling?

See you next week!

Custom year names, plus improvements and bug fixes

Hello, this is Claudio with a quick recap of what changed this week in the source code of Ruby on Rails.

Add year_format option to date_select tag

In Japan, 2000 A.D. is Heisei 12 in Wareki. Other countries like Israel and Thailand also have their own calendars.

date_select now takes a lambda option year_format that can be used to customize year names, e.g.: year_format: ->year { “Heisei #{year - 1988}”.

Support more HTTP cache controls

Add support for the stale-while-revalidate and stale-if-error extensions to the Cache-Control response header. Supporting them will make it easier to utilize reverse proxies and CDNs from Rails without resorting to hacks.

Reduce Memory Allocation when using pluck

This PR optimises ActiveRecord::Result#cast_values to avoid creating temporary arrays, reducing the number of objects allocated to 1 per row retrieved. 
Benchmark show that the new version is up to 1.5x faster.

Permit configuring the default service URL expiry

You can now specify the default expiry of URLs generated by Active Storage by setting config.active_storage.service_urls_expire_in. The default is 5 minutes.

Fix touch to behave consistently

The touch option recently added to increment! in Active Record was not updating update_at/on attributes when passed attribute names. The behavior has now been fixed.

Fix result of transform_values in AC::Parameters

This method (and transform_values!) was not consistently returning an instance of ActionController::Parameters. This PR (from a first-time contributor!) fixes it.

18 people contributed to Rails this past week, including 2 first-time contributors. Check out the list of open issues!

Among other news, a security vulnerability was disclosed this week so update Sprockets to the latest version if you haven’t yet.

Oh, and my talk about Active Storage at RailsConf 2018 is finally on YouTube. 🤗 Have a great weekend!

Faster record deletion, customized error messages, bug fixes, and more!

Greetings, all! This is Daniel, with the latest news about Ruby on Rails.

This Week’s Contributors

14 people contributed to Rails this past week, including 4 first-time contributors. Many thanks to all!

Are you looking to get involved? Check out the list of open issues!

Faster dependent destroying

Has GDPR got you deleting users and all their “likes”? The dependent: destroy option has been updated to use a linear algorithm, rather than a quadratic one. I like that!

Allow suffixing store attributes

Back in March we added the option to use prefixes for your store attributes. Well now you can use suffixes as well. Say goodbye to clashing method names!

Flexible error message customization

Ever find yourself wanting to override the default Active Model error message format for a particular model or attribute, rather than for the whole language? Well now you can!

Eager loading in development

In Rails 5.1 and 5.2 setting config.eager_load = true in development could cause the server to lock up. As I’m sure you could guess, we were eager to get this merged.

Fix round trip problem with params

Parsing nested params is not easy, but your controller tests may depend on it. Luckily we were able to handle it with Rack and a little bit of tender love.

But wait, there’s more! If you are eager for more Ruby on Rails news, check out the full list of commits from the past week. Otherwise, see you next week!

Improvements, bug fixes and more!

Hello everyone! This is Greg, with the latest news about Ruby on Rails!

This Week’s Contributors

13 awesome people contributed to Rails this past week!
If you’d like to be included here, why not check out the list of open issues?

Raise exception when column is already defined

With this change, migrations will raise an exception when defining an already defined column.

Align method signature with that of Time::at

ActiveSupport::TimeZone#at now accepts an optional second argument, containing (fractional) microseconds, just like Ruby’s Time::at does.

Avoid allocating column names where possible

When requesting columns names from database adapters, ActiveRecord:Result used to dup/freeze column names. This change prefers using fstrings, which cuts down on repeat allocations.

Parent record should not get saved with duplicate children records

Before this fix a duplicated child relations validation error didn’t propagate to the parent record, but now it is all fixed.

As always, there were many more changes to the Rails codebase than we can cover here - if you’re interested, you can check out the full listing of commits from this past weeks. Until next week!

Enumerable#index_with, transaction fixes, and more!

Hello everyone! This is Eugene, with a roundup of the last two weeks of activity in the Rails world. Let’s get started!

This Week’s Contributors

In the last two weeks, Rails saw contributions from 29 people, including 10 first-time contributors. Thank you all!

If you’d like to be included here, why not check out the list of open issues?

Add Enumerable#index_with

This new method converts an enumerable to a hash, where the keys are the enumerable’s elements and the values are determined by the provided block or argument.

Action Mailer now eager loads the mail gem

Loading the mail gem during boot avoids burdening the first request with the responsibility, and conveniently sidesteps a deadlock that the author encountered in their application.

Allow Range#=== and Range#cover? on Range

Active Support extends Range#=== to match other ranges, but a change to the native Ruby implementation broke it. This patch ensures that the behaviour will work on Ruby 2.6, and also adds it to Range#cover? for good measure.

Speed up xor_byte_strings by 70%

The benchmark included with this performance patch shows that it saves a cool 5 microseconds whenever Rails generates a CSRF token. 🐎

Roll back parent transaction when children fail to save

If a record’s associations contains valid but unsaveable data, it will now correctly fail to save and roll back its transaction.

Finalize transaction record state after real transaction

When a record was saved multiple times in the same transaction, its previous state wasn’t always immediately restored if the transaction was later rolled back.

Disable foreign keys during alter_table for SQLite3 adapter

Tables that are referenced by foreign keys can now be successfully altered when using the SQLite3 adapter.

In related news, Rails 6.0 will require a minimum SQLite version of 3.8.0.

As always, there were many more changes to the Rails codebase than we can cover here - if you’re interested, you can check out the full listing of commits from the last two weeks. Until next week!

Google Cloud Storage streaming downloads, performance improvements and more!

Hello everyone! This is Roque bringing you the latest news from the Rails world. I will cover the highlights from the last two weeks. Let’s get started!

This Week’s Contributors

39 people contributed to Rails in the last two weeks, including 9 for the first time! A big thank you to all of you!

If you’d like to see yourself on that board, why not check out the list of open issues, or get involved in the core discussion list.

Support streaming downloads from Google Cloud Storage

Active Storage now supports streaming downloads from Google Cloud Storage. You will need version 1.11 or greater of the gem google-cloud-storage.

Add option identify to ActiveStorage::Blob

This allows control over the content type identification performed by Active Storage. For instance, if identify is false, then you can provide your own content_type value.

Improve the performance of ActiveSupport::Inflector.ordinal

Big performance improvement for ordinal generation! The power of benchmarks-oriented solutions.

Use did_you_mean for spelling suggestions

Now that Rails requires Ruby 2.3 or greater, Rails will use the gem did_you_mean for spelling suggestions. The gem is shipped with Ruby, and automatically required when the Ruby process starts.

Fix logic on disabling commit callbacks

Callbacks were being called unexpectedly when errors occur due to a small issue with precedence of logical operators.

Reset CONTENT_LENGTH between test requests

If a POST request was followed by a GET request in a controller test, then the rack.input and RAW_POST_DATA headers from the first request would be reset but the CONTENT_LENGTH header would leak to the second request.

As always there were many more changes to the Rails codebase than we can cover here. But you can read all about them here! Until next week!

Arel merged to Active Record, faster image processing and more

Hello 🌧 from London! This is Kir, bringing you the latest Rails updates in this episode of the newsletter.

This Week’s Contributors

28 people contributed to Rails in the last week, including 3 for the first time! A big thank you to all of you!

If you’d like to see yourself on that board, why not check out the list of open issues, or get involved in the core discussion list.

Use ImageProcessing gem for Active Storage variants

ImageProcessing gem provides a wrapper around MiniMagic and ruby-vips, allowing you to change backends on the fly and benefit from libvips being up to 10x faster than ImageMagick.

Update ‘rails_welcome.png’ to reflect a more diverse population

The Getting Started picture that you can see in new Rails apps was updated with a more diverse population.

Support Active Storage attachment in presence validator

assert_presence_of now works with ActiveStorage attachments.

Merge Arel to Active Record

To simplify release management, Arel library hosted in rails/arel has been merged to ActiveRecord, and is now located in rails/rails.

As always there were many more changes to the Rails codebase than we can cover here. But you can read all about them here! Until next week!

RailsConf 2018 Edition

Hello 🌨 from Pittsburgh! RailsConf was amazing: more than a thousand attendees showing that Rails is more alive and welcoming than ever.

All the presentations will be available on YouTube in about a month. For now, you can take a sneak peek by browsing the slide decks: from Rails 6 to Active Storage, from Migrations to Testing, from Upgrades to API, from Router to Contributing, from GraphQL to Performance, from Collaboration to Communication, from Kafka to PostgreSQL, from Warden to Authorization, from Economy to Art, from Bugs to Security, from Containers to Crypto, from Interviews to History, from Teams to Trust, from Shopify to GitHub, from Engines to Crowdsourcing, from Mortality to Life, there was really something for everyone!

This Week’s Contributors

37 people contributed to Rails in the last week, including 9 for the first time! A big thank you to all of you!

If you’d like to see yourself on that board, why not check out the list of open issues, or get involved in the core discussion list.

Inclusive Language in Documentation Examples

A couple of changes to make the docs more inclusive of trans and non-binary individuals. Hurray! 💗🌈🏳️‍🌈

Add the nonce: true option for javascript_include_tag helper

Works the same way as javascript_tag nonce: true to support automatic nonce generation for Content Security Policy.

Improve performance of translation helper

A PR that is worth reading to learn how to benchmark a possible performance improvement using the right tools.

Don’t pass splat keyword arguments as a single Hash

Looking ahead at Ruby 2.6, which will raise a warning when a method is called with (*args). Declaring the arguments makes for more readable code.

Fix exception in AS::Timezone.all when any tzinfo data is missing

Time zones change every year, even multiple times a year. ActiveSupport::Timezone.all won’t raise an error even when a time zone is missing from TZInfo.

Output only one nonce in CSP header per request

Nonces from old requests were saved, causing the header to grow infinitely after every request.

Avoid blocking the server in #delete_matched

A fix to the newly added redis-cache-store feature of Rails 5.2. Calling delete_matched will no longer block the Redis server.

Coming back home after an amazing event like RailsConf is always tough. Can’t wait to see you all next year at RailsConf 2019 in Minneapolis from April 30th to May 2nd. Hopefully it won’t snow! 🤞– Claudio

Rails 5.2.0, performance optimizations, space-saving compression and more!

And now a Rails 🌩 News Flash 🌩! (Hint: we’ve got some big news this week, if you hadn’t heard). We take you now, live, to our reporter on the scene, Tim, for all the latest and greatest this week.

Rails 5.2.0 is out!

5.2.0 is officially among us, a little bit ahead of RailsConf this year. If you can’t wait until then to find out everything that this new release brings, do go read the original blog post that accompanied the release for all the details!

This Week’s Contributors

48 people contributed to Rails in the last two weeks, including an incredible 11 for the first time! A big thank you to all of you!

If you’d like to see yourself on that board, why not check out the list of open issues, or get involved in the core discussion list.

API controlIers now get a set of default headers

Though you may not need all these headers, there are specific instances where you may want them to enhance security, so it makes sense to have this configured on by default.

An optimization for the Query Cache middleware

This nice little optimization eliminated some array allocations, that you may benefit from if you have a large number of connection pools.

Avoid generating full changes hash on every save

By asking the mutation tracker for the list of changed attributes, some work can be skipped when generating the changes hash. This may be most noticeable for serialized attributes, for which calling #original_value can be significantly more expensive.

Fix ActiveSupport::Cache compression

A regression was found whereby compressed items in the cache store were taking up more space than their original, uncompressed versions. That is now fixed thanks to the great detective work shown in this PR!

As always there were many more changes to the Rails codebase than we can cover here. But you can read all about them here! Until next week!

Rails 5.2.0 FINAL: Active Storage, Redis Cache Store, HTTP/2 Early Hints, CSP, Credentials

Nearly 14 years since the first public version of Rails, it’s our pleasure to release yet another major upgrade to the framework in the form of 5.2.0 final. We’ve been diligently polishing Active Storage and the other big new components for stable release, and it’s great to see so many applications already running the release candidates in production. Basecamp and Shopify have both been running Rails 5.2.0 for quite a while.

This release comes just in time for RailsConf, which features sessions on the new encrypted credentials, a code review of Active Storage, advice on how to upgrade to a new Rails version, and a lot of Webpack talks.

You can read in even more detail about everything that’s new in Rails 5.2 in the newly finished release notes.

Note that rails/master development is now targeting Rails 6.0.

Many thanks to Rails core, Rails contributors, and everyone else who’ve helped with code, documentation, bug reports, and whatever else to get Rails 5.2.0 out the door. It’s amazing to have over 400 code contributors with fingerprints on this release.

Feature highlights

It’s been too hard to deal with file uploads in Rails for too long. Sure, there’s been a lot of fine plugins available, but it was overdue that we incorporated something right into the framework. So now we have!

With the new Active Storage framework in Rails 5.2, we’ve solved for the modern approach of uploading files straight to the cloud. Out of the box, there’s support for Amazon’s S3, Google’s Cloud Storage, and Microsoft Azure Cloud File Storage.

If you’re dealing with images, you can create variants on the fly. If you’re dealing with videos or PDFs, you can create previews on the fly. And regardless of the type, you can analyze uploads for metadata extraction asynchronously.

Active Storage was extracted from Basecamp 3 by George Claghorn and yours truly. So not only is the framework already used in production, it was born from production. There’s that Extraction Design guarantee stamp alright!

Speaking of extractions, Jeremy Daer has untangled the long jungle twine of hacks we were using at Basecamp to employ Redis for general partial, fragment, and other Rails caching jobs. There’s a sparkling new Redis Cache Store that incorporates all those years of veteran hacks into a cohesive unit that anyone can use.

This new Redis Cache Store supports Redis::Distributed, for Memcached-like sharding across Redises. It’s fault tolerant, so will treat failures like misses, rather than kill the request with an exception. It even supports distributed MGETs for that full partial collection caching goodness.

This comes together with a massive leap forward for cache efficiency with key recycling and compression both available by default. For Basecamp, it meant improving the cache lifetime by two orders of magnitude! We went from having caches trashed in as little as a day to having caches last for months. If you’re using partial caching and the nesting doll strategy, your cache lifetime will improve dramatically between these two changes.

We’ve also embraced the cherry of HTTP/2 with early hints through the work of Aaron Patterson and Eileen Uchitelle. This means we can automatically instruct the web server to send required style sheet and JavaScript assets early. Which means faster full page delivery, as who wouldn’t want that?

On the topic of performance, Rails now ships with Bootsnap in the default Gemfile, created by our friends at Shopify. It generally reduces application boot times by over 50%.

Rails has always been in the forefront of making your web applications more secure, leading the way with built-in CSRF and XSS protection and we’ve enhanced that further in Rails 5.2 with the addition of a new DSL that allows you to configure a Content Security Policy for your application. You can configure a global default policy and then override it on a per-resource basis and even use lambdas to inject per-request values into the header such as account subdomains in a multi-tenant application.

But it’s not all just new starry-eyed wonders. In Rails 5.1, we added encrypted secrets. These secrets were like the old secrets but, uhm, more secret, because, you know, ENCRYPTION! Confusing? Yes. Why would you want secrets that weren’t really secret? Well, you don’t.

In Rails 5.2, we’ve rectified the mess by deprecating the two different kinds of secrets and introduced a new shared concept called Credentials. Credentials, like AWS access keys and other forms of logins and passwords, were the dominant use case for secrets, so why not just call a spade a spade. So spade it is!

Credentials are always encrypted. This means they’re safe to check into revision control, as long as you keep the key out of it. That means atomic deploys, no need to mess with a flurry of environment variables, and other benefits of having all credentials that the app needs in one place, safe and secure.

In addition, we’ve opened up the API underlying Credentials, so you can easily deal with other encrypted configurations, keys, and files.

Since Rails 5.1, we’ve also made great strides with Webpacker. So Rails 5.2 is meant to pair beautifully with the new Webpacker 3.0 release. Rails has fully embraced modern JavaScript with a pre-configured build pipeline run by Webpack. We keep strengthening that relationship.