Rails 4.2.11.1, 5.0.7.2, 5.1.6.2, 5.2.2.1, and 6.0.0.beta3 have been released!

Hello everyone!

Rails 4.2.11.1, 5.0.7.2, 5.1.6.2, 5.2.2.1, and 6.0.0.beta3 have been released! These contain the following important security fixes. It is recommended that users upgrade as soon as possible:

Rails 5.2.2.1 and 6.0.0.beta3 also contain the following fix:

The released versions can be found in the usual locations, and you can find a list of changes on GitHub:

If you’re not able to upgrade immediately workarounds have been provided on the advisory pages in the Google Rails Security Group.

We’ve done our best to minimize any impact to your applications, but if you run in to any issues, please file a ticket and we’ll do our best to help!

If you run in to security issues, please follow the reporting process which can be found here.

SHA-256

If you’d like to verify that your gem is the same as the one we’ve uploaded, please use these SHA-256 hashes.

$ shasum -a 256 *4.2.11.1.gem*
5ec3df89a6796f18006198b95e6849ea736bc6170da0daf7d8cec9e388a49ca3  actionmailer-4.2.11.1.gem
50f296dfd8cfbb071fa1008c5157ed22871dbe0ddddc4cc1ec9c1235a66eb466  actionpack-4.2.11.1.gem
373d6065baf091996e0d6d36b99080ceeee323038fcf218ff39f2e839195fb74  actionview-4.2.11.1.gem
b21e40e0c147fc24c939fa1b4b1e3677ffae22b9c125a881ba587a6d7260c14b  activejob-4.2.11.1.gem
63d898086a8d2d0a493ebb4d8c9376c6f9d3dfe846f7aa1f70615a6e5a063db0  activemodel-4.2.11.1.gem
b7e0744484c8a9fe2c123657cfb5bbf678657555eeeeacf0d449ff0f228f3d1e  activerecord-4.2.11.1.gem
264782453d1912cf99f80b6bbf3f2e0e0592874e740e2c66f4dbad02903a78ed  activesupport-4.2.11.1.gem
b4b6536187eab61696358d851e043d60be3fc8313da67815467bb4968a8e9bfb  rails-4.2.11.1.gem
35b430dfd63028401c19dbfe4b319bebd59ea0b5a6b818d85731aa9a7e104eae  railties-4.2.11.1.gem
$ shasum -a 256 *5.0.7.2.gem*
525621c9bde0e729e566e9ebdaf23945cf0cc0b11e731f3f74c7d4d839e97b01  actioncable-5.0.7.2.gem
f5e616088e556244bf6cf6e6236e9a7bbef0d2bd2627b97c19c53096130b4756  actionmailer-5.0.7.2.gem
3ad093d8fcc08163b4ce38136b933c4c38c4973c872b155023fec11523a35eed  actionpack-5.0.7.2.gem
1c52732589d776ba01590233b44c33f679ec62c9bada89ebed3755066eb00823  actionview-5.0.7.2.gem
d122d5414f485713eabd4e5e866b1a238b1179ec5fd33d81cb2c5f6d751ce9df  activejob-5.0.7.2.gem
395d43d408239936668f04cab80bc64b50b08e414fe866664e1bf717e265aaca  activemodel-5.0.7.2.gem
8eb57c48689536545e08b87a6b45b5d2b30a19f1cc06d2772aad9694083ae11a  activerecord-5.0.7.2.gem
bc336a970b5d1c2c2e9e1494afd6ff585680dbab6f12d95acd17ee1be8d6de09  activesupport-5.0.7.2.gem
3ce2eac8fa58ce138e3e2a2fa9b544c8f43128e0c24d0a1d8d751b3a515bb82a  rails-5.0.7.2.gem
4dc24c2dbe4b89ce7c2975cbdb601fcb868de3f1992c00629991033a86059c18  railties-5.0.7.2.gem
$ shasum -a 256 *5.1.6.2.gem*
381b8945ed2bf7aea3e56be8ec6265a9db0e6443d5d1be169484b91ba3041926  actioncable-5.1.6.2.gem
e1c30d19963b365db87daf122620dc9cb006938f0f6d3ac28e0f2da511fd1b6c  actionmailer-5.1.6.2.gem
56c17b7a665a8b1ac816d7ed9fda5d36e605fc4951b0b9455bf464f2ba34d08c  actionpack-5.1.6.2.gem
127da709aa88c749c3723b7fc3b02bbaf22767f1114d4910cc626eba6027e7e5  actionview-5.1.6.2.gem
d6511d6cdf23920bfa1b0062966d5a2468cc8ee705b921e2ef0547bee541c9ac  activejob-5.1.6.2.gem
b324ff341f2410a509e655000206b521fed43ff295de2589eb5eeed18d931985  activemodel-5.1.6.2.gem
3f45f3bbdaf0e6583853393adac564457def668fc26023093e061dc6b977eebd  activerecord-5.1.6.2.gem
ed88feb866ad705e79cd5ca6c8f3dd39d8571df02abf0d10b34889576c93bb4f  activesupport-5.1.6.2.gem
8e721f8e6c7ea0dfd6dbf7fe215f2c40b1de5d104b6cf5d1e1313dc02be640e9  rails-5.1.6.2.gem
a385a8620eb3a5f11c2ac2c2d50cc2dba268dfc0e26b07a566b03a2dbff17ddf  railties-5.1.6.2.gem
$ shasum -a 256 *5.2.2.1.gem*
4125771d4a3c6fb9a38d1617eae08abdb2a0418c2f23d8f891bfa1f3736d15ca  actioncable-5.2.2.1.gem
622e4fae71442c5d7df7e77eeb932f17c27093055a737d4a7a5b4e0d407c4c47  actionmailer-5.2.2.1.gem
8a223ad2f06e51ee624993589b77dc4401645bb3bda3faa5ab04758cf39cab4d  actionpack-5.2.2.1.gem
3f9c1868cd07708bddec82a83f8091d48e6f529bb4c7c25167e428f50aeef278  actionview-5.2.2.1.gem
b8271b919108a743bbd79d6da3d3ee9bcdd7529294175eaf7a16d26caf984251  activejob-5.2.2.1.gem
55d56bcaefcff47d85bfac98d40e57d5ac0b923575abb5fdd0dd6a064f381381  activemodel-5.2.2.1.gem
e21d5ff1f2a0f79aa446e84563978f628c42caf1db7b4804c43e585bf28bb600  activerecord-5.2.2.1.gem
4664ace24b43227a42d943cfc8aae59dbe79091ee70cf7be257b4553e50fd8bf  activestorage-5.2.2.1.gem
d0a7b92b46e34de7cca05ed74d9659b205f91a0a7fda9f2ea5a3f53ae00b2a81  activesupport-5.2.2.1.gem
e45c26eff3d7bdfa989ab884754f25d4a274b4b6324df9d9a4a7168cc32ccbe0  rails-5.2.2.1.gem
44b2cfe87f78cb3069362a15c8c3b49ff5a02ea01d60dd2685e1112a9e01e938  railties-5.2.2.1.gem
$ shasum -a 256 *6.0.0.beta3.gem*
749a4eed1702e463fef97b2dfa0aed961b6a13931f50ac92bcc176b98bb5159e  actioncable-6.0.0.beta3.gem
b7c4936ffa9697a5d6ea397a28d1f67f3847aebe76a8fa717c61f8ee81d3efcc  actionmailbox-6.0.0.beta3.gem
be8af2a7d9af39f4ee0252b5104204c6b36d7d2ca0ac0bdc0063230c247e711a  actionmailer-6.0.0.beta3.gem
7d070d5853f19c685d22a790d6be919356727a281ab2b30c8104c30dc5e045f4  actionpack-6.0.0.beta3.gem
faf1f28e70a9faf04ac2077fb4e2f518ac76a29e8e1c487f3d9658118553eaf0  actiontext-6.0.0.beta3.gem
91c72834addba79ff315c56f2924ee1a8fba99db45c65ccd0406e4b611d7b1a4  actionview-6.0.0.beta3.gem
c8f76f01156bc6542d17e116b4c9971f969f663badacd2e0cf036baaff796ae9  activejob-6.0.0.beta3.gem
3bc73125ba7105391779ee41e929a7d2b989a733efe86c84594654ae26a7e95a  activemodel-6.0.0.beta3.gem
d31e3c6ae3207dd27bc4fed178dd43c592b1a3d42f3df3f0780abbb27e8ea3f1  activerecord-6.0.0.beta3.gem
d4a743473431153c4f502409bb8d9dc57d9252687f85a94a932772eed6f0f95d  activestorage-6.0.0.beta3.gem
7193da2b92e4f9da95e4cfa2a878911cb420f535343613df0398dfe60ff9c868  activesupport-6.0.0.beta3.gem
b08df88e745edaca9b38162e115bc14935bbf6749eaf4809745c9679d7816c07  rails-6.0.0.beta3.gem
24aa0b8df380fc847ae0eb4d951eeb3b4f9d388aff84eab5f7a43c477c423c95  railties-6.0.0.beta3.gem

reselect, negative enum scopes and more!

Why hello there! Tim here bringing you all the latest and greatest from This Week In Rails.

Negative scopes for enum values

Some sugar around enum values allows you to make negative scopes such as

Post.not_drafted # => where.not(status: :drafted)

New method: reselect

Allows you to change a previously set select statement in the same manner to rewhere and reorder, e.g.

Post.select(:title, :body).reselect(:created_at)

#size fixed when using SELECT DISTINCT

#size_ would ignore the DISTINCT in the select, giving a different result to #count. This is now fixed!

Active Storage’s _blob loading fixed

If you attached a has_one_attachment attachment, you may have found that the attachment’s _blob method would have returned nil. This was fixed by assigning the blob when the attachment is assigned.

22 people contributed to Rails since our last issue; you can see the full list of changes here.

Until next week!

Rails 6.0.0 beta2 released

We’re marching one step closer to the final release of Rails 6 with this second beta. We’ve fixed a bunch of issues and added a few minor features, but the big change is switching to Xavier’s new Zeitwerk library for handling autoloading. It’s a big, structural change to how we require dependencies at runtime, and it should remove a bunch of the legacy warts, and the weird gotchas. Xavier wrote up a long piece on it you should check out.

Otherwise things are much the same as they were with the first beta. I encourage you to read the release notes for that to understand the big picture of 6.0.

You can peruse all the 532 commits we’ve made since the first beta.

We are still kinda on track with our published timeline for the final Rails 6.0 release, so consult that plan for your migration planning, but please do help us already by testing your application on beta2! I’d also encourage anyone with a moderate level of Rails experience to start any new app using beta2, rather than the Rails 5.2.x series. Basecamp and Shopify are both already running Rails 6.0.0.beta2 in production. This isn’t some rickety-shack release.

This release, and all releases leading up to Rails 6.0 final, was shepherded by release manager Rafael França with support by Kasper Timm Hansen.

Thanks again to everyone who keeps working on making Rails better!

Zeitwerk integration in Rails 6 (Beta 2)

The second beta of Rails 6 is about to ship, and includes Zeitwerk integration.

While Rails 6 final is going to have proper documentation about it, this post will help understanding this feature meanwhile.

Highlights

  • You can now robustly use constant paths in class and module definitions:

    # Autoloading in this class' body matches Ruby semantics now.
    class Admin::UsersController < ApplicationController
      # ...
    end
    
  • All known use cases of require_dependency have been eliminated.

  • Edge cases in which the autoloaded constant depended on execution order are gone.

  • Autoloading is thread-safe in general, not just for the currently supported use cases with explicit locks like web requests. For example, you can now write multi-threaded scripts to be run by bin/rails runner and they will autoload just fine.

Also, applications get some performance benefits for the same price:

  • Autoloading a constant no longer involves walking autoload paths looking for a relative match in the file system. Zeitwerk does one single pass and autoloads everything using absolute file names. In addition, that single pass descends into subdirectories lazily, only when the namespaces are used.

  • When an application is reoloaded due to changes in the file system, code in the autoload paths of engines that were loaded as gems won’t be reloaded anymore.

  • Eager loading eager loads not only the application, but also the code of any gem that is managed by Zeitwerk.

Autoloading modes

Rails 6 ships with two autoloading modes: :zeitwerk and :classic. They are set using the new configuration point config.autoloader.

Zeitwerk mode is the default in Rails 6 for CRuby, automatically enabled by

load_defaults "6.0"

in config/application.rb.

Applications can opt-out putting

config.autoloader = :classic

after the line that loads the defaults.

State of the API

While a first API for Zeitwerk mode is converging, this is still a bit exploratory right now. Please, check the current documentation if your version of Rails is newer than 6.0.0.beta2.

Autoload paths

The configuration point for autoload paths remains config.autoload_paths, and if you push by hand to ActiveSupport::Dependencies.autoload_paths during application initialization, that will also work.

require_dependency

All known use cases of require_dependency have been eliminated. In principle, you should just delete all these calls in the code base. See also the next section about STIs.

STIs

Active Record needs to have STI hierarchies fully loaded in order to generate correct SQL. Preloading in Zeitwerk was designed for this use case:

# config/initializers/preload_vehicle_sti.rb

autoloader = Rails.autoloaders.main
sti_leaves = %w(car motorbike truck)

sti_leaves.each do |leaf|
  autoloader.preload("#{Rails.root}/app/models/#{leaf}.rb")
end

By preloading the leaves of the tree, autoloading will take care of the entire hierarchy upwards following superclasses.

These files are going to be preloaded on boot, and on each reload.

Rails.autoloaders

In Zeitwerk mode, Rails.autoloaders is an enumerable that has two Zeitwerk instances called main, and once. The former is the one managing your application, and the latter manages engines loaded as gems, as well as anything in the somewhat unknown config.autoload_once_paths (whose future is not bright). Rails reloads with main, and once is there just for autoloading and eager loading, but does not reload.

Those instances are accessible respectively as

Rails.autoloaders.main
Rails.autoloaders.once

but since Rails.autoloaders is an enumerable, there won’t be too many use cases for direct access, probably.

Inspecting autoloaders activity

If you want to see the autoloaders working, you can throw

Rails.autoloaders.logger = method(:puts)

to config/application.rb after the framework defaults have been set. In addition to a callable, Rails.autoloaders.logger= accepts also anything that responds to debug with arity 1, like regular loggers do.

If you want to see the activity of Zeitwerk for all instances in memory (both Rails’ and others that might be managing gems), you can set

Zeitwerk::Loader.default_logger = method(:puts)

at the top of config/application.rb, before Bundle.require.

Backwards incompatibility

  • For files below the standard concerns directories (like app/models/concerns), Concerns cannot be a namespace. That is, app/models/concerns/geolocatable.rb is expected to define Geolocatable, not Concerns::Geolocatable.

  • Once the application has booted, autoload paths are frozen.

  • Directories in ActiveSupport::Dependencies.autoload_paths that do not exist on boot are ignored. We are referring here to the actual elements of the array only, not to their subdirectories. New subdirectories of autoload paths that existed at boot are picked up just fine as always. (This may change for final.)

  • A file that defines a class or module that acts as a namespace, needs to define the class or module using the class and module keywords. For example, if you have app/models/hotel.rb defining the Hotel class, and app/models/hotel/pricing.rb defining a mixin for hotels, the Hotel class must be defined with class, you cannot do Hotel = Class.new { ... } or Hotel = Struct.new { ... } or anything like that. Those idioms are fine in classes and modules that do not act as namespaces.

  • A file should define only one constant in its namespace (but can define inner ones). So, if app/models/foo.rb defines Foo and also Bar, Bar won’t be reloaded, but reopened when Foo is reloaded. This is strongly discouraged in classic mode anyway though, the convention is to have one single main constant matching the file name. You can have inner constants, so Foo may define an auxiliary internal class Foo::Woo.

Active Record bug fixes, faster Date#advance, and more!

Hello everyone! This is Eugene, with a selection of interesting improvements to Rails merged in the past week.

Don’t load app environment when editing credentials

Support for per-environment credentials is coming in Rails 6.0, but adding a new environment wasn’t always easy: if your application accessed credentials during boot, the credentials:edit command would fail to run, which would in turn prevent you from adding the missing credentials. Oops!

All queries should return correct results even if they include large numbers

When prepared statements are enabled, querying an integer column with an out-of-range value causes an error in the underlying database driver. To work around this issue, Active Record used to refuse to run the query and always return a negative result, e.g. ActiveRecord::RecordNotFound.

This approach worked for simple queries, but gave incorrect results for more complex ones. Out-of-range values are now converted to “impossible” predicates instead (e.g. WHERE 1=0), which allows the query to run without an error while still producing the correct result.

Speaking of large numbers: this pull request, opened 18 months ago, was number 30,000 on the Rails repository. 🎈

Fix year value when casting a multi-parameter time hash

Values stored in TIME columns in the database are mapped to Time objects in Ruby. The latter includes date parts, where the former doesn’t; to deal with this discrepancy, a default date of January 1st, 2000 is always assigned.

When a multi-parameter time value—as generated by the time_select helper—was assigned to an attribute, its year would be set to 1970 instead, producing a different result depending on where the value came from.

With this fix, time attributes have fully joined us in the 21st century. 🖖

Faster and more memory-efficient Date#advance

This method was copying its options hash unnecessarily. Now that it doesn’t, it’s both faster and allocates less memory.

28 people contributed to Rails since our last issue; you can see the full list of changes here.

Until next week!

Rails 6.0.0 beta1, and more

Daniel here, writing from chilly NYC to bring you the latest Rails news.

Rails 6.0.0 beta1

Many thanks to everyone who helped get this amazing release together. It includes Action Text and Action Mailbox, both recently merged into Rails. Try it out today!

New command to change databases

Have you ever created a new Rails app without specifying the database system upfront, then realized you need to switch over from SQLite to PostgreSQL? That change is now as simple as running: bin/rails db:system:change --to=postgresql

Improved multi-db errors

I think we can all appreciate helpful error messages. Many thanks to Eileen for helping us out, and for all of the incredible work to support multiple databases.

Action Cable Testing

The test helpers from the action-cable-testing gem are now fully merged into Rails. Testing your cables has never been easier.

Endless ranges in where conditions

Ruby 2.6 introduced endless ranges. In Rails 6 we will be able to use them in where conditions: features.where(awesomeness: 10..)

Don’t watch your parents

Before this change, if a directory to be watched was not present in the project, Rails would watch that directory’s parent directory instead. In some cases this could lead to watching the entire Rails root directory.

72 people contributed to Rails over the past month. There are still plenty of open issues that could use your help. Will we see your name on the list next week?

Rails 6.0.0 beta1: Action Mailbox, Action Text, Multiple DBs, Parallel Testing, Webpacker by default

The first beta release of Rails 6 is here! It’s absolutely packed with amazing new stuff that we’re so excited to share. There are two major new frameworks – Action Mailbox and Action Text – and two important scalable-by-default upgrades in great multiple database support and parallel testing.

Action Mailbox routes incoming emails to controller-like mailboxes for processing in Rails. It ships with ingresses for Amazon SES, Mailgun, Mandrill, Postmark, and SendGrid. You can also handle inbound mails directly via the built-in Exim, Postfix, and Qmail ingresses. The foundational work on Action Mailbox was done by George Claghorn and yours truly.

Action Text brings rich text content and editing to Rails. It includes the Trix editor that handles everything from formatting to links to quotes to lists to embedded images and galleries. The rich text content generated by the Trix editor is saved in its own RichText model that’s associated with any existing Active Record model in the application. Any embedded images (or other attachments) are automatically stored using Active Storage and associated with the included RichText model. The foundational work on Action Text was done by Sam Stephenson, Javan Makhmali, and yours truly.

The new multiple database support makes it easy for a single application to connect to, well, multiple databases at the same time! You can either do this because you want to segment certain records into their own databases for scaling or isolation, or because you’re doing read/write splitting with replica databases for performance. Either way, there’s a new, simple API for making that happen without reaching inside the bowels of Active Record. The foundational work for multiple-database support was done by Eileen Uchitelle and Aaron Patterson.

With parallel testing support, you can finally take advantage of all those cores in your machine to run big test suites faster. Each testing worker gets its own database and runs in its own thread, so you’re not pegging one CPU to 100% while the other 9 sit idle by (y’all do have a 10-core iMac Pro, right 😂). Hurray! The foundational work for parallel-testing support was done by Eileen Uchitelle and Aaron Patterson.

Webpacker is now the default JavaScript bundler for Rails through the new app/javascript directory. We’re still using the asset pipeline with Sprockets for CSS and static assets, though. The two integrate very nicely and offer the best trade-off of advanced JavaScript features with an it-just-works approach to other assets.

Those are just some of the marque additions, but Rails 6.0 is also packed with minor changes, fixes, and upgrades. Just some I’d call out: Proper Action Cable testing, Action Cable JavaScript rewritten in ES6, protection against DNS rebinding attacks, and per-environment credentials. Also, Rails 6 will require Ruby 2.5.0+ now. You can check out everything in the individual framework CHANGELOG files for the nitty-gritty rundown.

Finally, you should pay attention to Xavier Noria’s new Zeitwerk code loader for Ruby. It didn’t make the integration cut for beta1, but starting with beta2, it’ll be the new autoloader for Rails. Be prepared to say goodbye to any lingering require or require_dependency calls in your code!

We are still roughly on track with our published timeline for the final Rails 6.0 release, so consult that plan for your migration planning, but please do help us already by testing your application on beta1! I’d also encourage anyone with a moderate level of Rails experience to start any new app using beta1, rather than the Rails 5.2.x series. Basecamp is already running Rails 6.0.0.beta1 in production, and both Shopify and GitHub and surely others will follow close thereafter. This isn’t some rickety-shack release.

This release, and all releases leading up to Rails 6.0 final, was shepherded by release manager Rafael França with support by Kasper Timm Hansen.

Thanks again to everyone who keeps working on making Rails better! It’s incredible that we’re still able to keep this intense rate of improvement going after all these years. Rails has never been in fitter shape to help the broadest number of web developers build excellent apps in a way they love. Let joy be sparked!

Timeline for the release of Rails 6.0

We’ve made enough progress towards the vision for Rails 6.0 that it makes sense to share our aspirational timeline for release. “Aspirational” being the key word, more so than “release” 😄. Software rarely ships on time, and we’ve had plenty of aspirational release dates that came and went in the past. But if optimism isn’t part of the fun of open source, then where would we be?

So. This is the timeline as we currently hope to see it:

  • January 15: Beta 1. We’ll merge the two new frameworks, Action Mailbox and Action Text, for this release.
  • February 1: Beta 2. We’ll make sure any other major improvements are included by then.
  • March 1: Release Candidate 1. We go feature complete by here.
  • April 1: Release Candidate 2. This should really be ready to ship, only new blockers will hold us back.
  • April 30: Final release. Ship and celebrate the release of Rails 6.0 at RailsConf 2019!

It always looks so nice and neat when laid out like that, right? Like some serious engineers did some serious engineering to figure this out. And not just a bunch of software writers plotting down their hopes and dreams. But yeah, it’s really the engineering part we went for (no it wasn’t).

Worth noting: Rails 6.0 will require Ruby 2.5+! So you can get ready by making sure you’re already running this version of Ruby. Also note that following the release of Rails 6.0, only Rails 6.x.y and Rails 5.2.x are guaranteed to receive both major and minor security fixes by Rails core. (As always, we may still choose to provide fixes further back, but there’s no guarantee).

As always, please help us make this a reality by running rails/master for new apps and existing ones, if you sport that High Adventure gene (aka no risk of getting fired if you hit a bug). Basecamp 3 is already running rails/master in production, so you know the main branch is at least in pretty good working order!

Our release manager for Rails 6.0 will be Rafael França with backup from Kasper Timm Hansen 🙏

To Rails Six Oh And Beyond! 🚀🚂

George joins Rails Core and Action Mailbox introduced

Hello. This is Wojtek with a short list of news from Rails world.

George joins Rails Core

George Claghorn is now a member of the Rails core team. Welcome George!

Introducing Action Mailbox for Rails 6

Action Mailbox is the brand new framework coming to Rails 6 extracted from Basecamp.

Add ActiveRecord::Base.connected_to?

Another handy method added to support multiple databases.

Fix numericality equality validation on floats

By casting values to BigDecimal comparision on validation is now more precise.

19 people contributed to Rails last week making lot of improvements.
Until next time!

Introducing Action Mailbox for Rails 6

Action Mailbox is the second brand new framework coming to Rails 6 (the first was Action Text). It serves to route incoming emails to controller-like mailboxes for processing in Rails. It ships with ingresses for Amazon SES, Mailgun, Mandrill, and SendGrid. You can also handle inbound mails directly via the Postfix ingress.

The inbound emails are turned into InboundEmail records using Active Record and feature lifecycle tracking, storage of the original email on cloud storage via Active Storage, and responsible data handling with on-by-default incineration. These inbound emails are routed asynchronously using Active Job to one or several dedicated mailboxes, which are capable of interacting directly with the rest of your domain model.

The framework was, like Action Text and Active Storage, extracted from Basecamp 3. We’ve been using a related approach to route everything from forwarded emails to email replies to messages and discussions. After extracting the ideas into Action Mailbox, we reintegrated the framework into Basecamp, and we’ve been running the code we’re sharing today for over a month in production.

Yes, Rails already had an anemic way of receiving emails using Action Mailer, but it was poorly flushed out, lacked cohesion with the task of sending emails, and offered no help on integrating with popular inbound email processing platforms. Action Mailbox supersedes the receiving part of Action Mailer, which will be deprecated in due course.

Rails 6 is getting closer, but it’s still a ways off – we’re hoping to start the beta process in early 2019. Action Mailbox is already in pretty decent shape, though, and you can even use it with Rails 5.2 applications, if you fancy dancing on the wild side. Just be prepared for things changing as we work our way through community review and towards merging it into rails/rails.

The Action Mailbox framework is based off ideas hatched by Jeremy Daer, and this particular implementation was done as a collaboration between yours truly and George Claghorn.

As part of the introduction of Action Mailbox, I plan to record a video showing off the basics in the near future. But the code is ready and somewhat documented for anyone to dive into already. So why sit on a good thing!

Between Action Text and Action Mailbox, Rails 6 is already shaping up to be one of the biggest releases in the history of the framework. And we’re not even done yet! Our plan is tentatively to have a release candidate version ready for RailsConf 2019 in Minneapolis. Please help us make that promise a reality by trying out Action Mailbox!