...Rails has a method ActiveRecord::Relation#merge that can merge ActiveRecord scopes. However, its behavior has never been clear, and in Rails 7 it still discards conditions on the same...

Every Rails response has a default ETag header. In theory this would enable caching for multiple requests to the same resource. Unfortunately the default ETags produced by Rails are effectively...

...random, meaning they can never match a future request. Understanding ETags When your Rails app responds with ETag headers, future requests to the same URL can be answered with an...

...1M downloads), and geordi (> 200k downloads) Developing a Ruby gem is different from developing Rails applications, with the biggest difference: there is no Rails. This means: no defined structure (neither...

...to require all files yourself no active_support niceties Also, their scopes differ. A Rails application usually combines many libraries with custom code. It runs on a given version of...

TL;DR When using Cache-Control on a Rails application, make sure the Vary: Accept header is set. Proxy caching is a good feature to serve your publicly visible application...

...but also affects proxies delivered by ISPs. Unfortunately, there is a little problem in Rails < 6.1 when delivering responses for different MIME-types. Say you have an arbitrary route in...

This card shows how to upgrade a Rails 2 application from Rails 2.3.8 through every single patch level up to 2.3.18, and then, hopefully, Rails LTS. 2.3.8 to 2.3.9

...release has many minor changes and fixes to prepare your application for Rails 3. Step-by-step upgrade instructions: Upgrade rails gem Change your environment.rb so it says RAILS_GEM...

...ActiveRecord scope. Depending on what you want to achieve, this is quite easy with Rails 7, and a bit more complicated with Rails 6 and below, or when the inverse...

...to get all users which are not part of User.admins, say: User.where.not(id: User.admins) Rails will generate a query like the following. SELECT * FROM users WHERE id NOT IN (SELECT...

Rails gives you migrations to change your database schema with simple commands like add_column or update. Unfortunately these commands are simply not expressive enough to handle complex cases.

...card outlines three different techniques you can use to describe nontrivial migrations in Rails / ActiveRecord. Note that the techniques below should serve you well for tables with many thousand rows...

...subject line for each new mailer method. class SubjectPrefixInterceptor def self.delivering_email(message) message.subject = "[#{Rails.env}] #{message.subject}" end end unless Rails.env.production? ActionMailer::Base.register_interceptor(SubjectPrefixInterceptor) end Define it in an initializer...

@allowlists ||= {} @allowlists[environment] ||= Allowlist.new(config.fetch(environment, {})) end private def config @config ||= YAML.load_file(Rails.root.join('config/mail_allowlist.yml')).freeze end end extend ClassMethods end class AllowlistInterceptor def self.delivering_email(message) allowlist = AllowlistConfig.for...

...deploys or servers If you save your uploads to a made up directory like "RAILS_ROOT/uploads", this directory goes away after every deploy (since every release gets a new). Also...

Only two folders are, by default, shared between our application servers and deployments: "RAILS_ROOT/storage" and "RAILS_ROOT/public/system" (note that this might be different if you are not hosting...

...table that is missing them. You can use the add_timestamps macros for that. Rails >= 4.2 Since Rails 4.2 add_timestamps also adds a NOT NULL constraint by default. So...

...SET updated_at = '#{time}'" # Restore NOT NULL constraints to be in line with the Rails default change_column_null :shows, :created_at, false change_column_null :shows, :updated_at, false...

Programatically invoke Rails generators Require the generator, instantiate it and invoke it (because generators are Thor::Groups, you need to invoke them with invoke_all). Example: require 'generators/wheelie/haml/haml_generator'

...HamlGenerator.new('argument').invoke_all Other ways: Rails invokes its generators with Rails::Generators.invoke ARGV.shift, ARGV. From inside a Rails generator, you may call the inherited Thor method invoke(args=[], options...

Note: Modern Rails has two build pipelines, the asset pipeline (or "Sprockets") and Webpacker. The principles below apply for both, but the examples shown are for Sprockets.

...request these assets again and again on every request. There is no magic in Rails that gives you automatic caching for assets. In fact, if you haven't been paying...

github.com

The new params.expect method in Rails 8 improves parameter filtering, addressing issues with malformed input and enhancing security. It provides a cleaner, more explicit way to enforce the structure and...

...hash or array) is provided for the permitted attributes. Example Basic Usage # Old before Rails 8 user_params = params.require(:user).permit(:name) # New since Rails 8 user_params = params.expect(user...

...the config.x configuration in combination with config_for to configure global settings for your Rails 4.2+ application. Example In your config/application.rb assign the settings from e.g. config/settings.yml as follows:

class Application < Rails::Application config.x.settings = config_for(:settings) end end The config/settings.yml might look as follows: shared: &shared email: info@example.com google_analytics: container: UA-123456-12 test: <<: *shared

Method delegation in Rails can help you to keep your code organized and avoid deep call chains (law of demeter) by forwarding calls from one object to another. Rails provides...

...method_missing(method_name, *args, &block) @user.public_send(method_name, *args, &block) end end Rails shortcut: delegate_missing_to Because this is such a common pattern (e.g. for building something...

...rolls back the transaction, nothing will be saved. The user will probably see a Rails error box. Improving the user experience In 99% of all cases adding a uniqueness key...

...is guaranteed. There are however cases where you want to improve the user behavior (Rails error box) or reduce the number of exceptions e-mailed to your / collected by your...

...readable form of the attribute: Person.human_attribute_name(:first_name) # => "First name" By default Rails will use String#humanize to format the attribute name, e.g. by replacing underscores with spaces...

...If no explicit translation is found, String#humanize is used. This card explains where Rails will look for custom attribute name translations in your locale files. Tip

Rails middlewares are small code pieces that wrap requests to the application. The first middleware gets passed the request, invokes the next, and so on. Finally, the application is invoked...

...can run rake middleware to get the ordered list of used middlewares in a Rails application: $> rake middleware use Webpacker::DevServerProxy use Rack::Sendfile use ActionDispatch::Static use Rack::LiveReload...

...inside. You can modify it there, and export it as an image. Option B: Use rails-erd Install rails-erd following the steps in their installation instructions. Run bundle exec...

...diagram, this is cumbersome on large projects, and can't be automated. You can use rails-erd instead. As an example, here is a Rake task where we render only...

When dealing with time zones in Rails, there is one key fact to keep in mind: Rails has configurable time zones, while Ruby is always in the server's time...

...actually disable time zones, because their existence is a fact. You can, however, tell Rails the only single time zone you'll need is the server's. config.time_zone = "Berlin...

...four variants, that add a more intuitive workflow when working with nested attributes in Rails + Unpoly: Without JS With HTML template and JS With HTML template and JS using dynamic...

Rails migrations allow you to use a change method whose calls are automatically inverted for the down path. However, if you need to some path-specific logic (like SQL UPDATE...

...at the same time. If you were to define define all 3 of them, Rails would only run change and ignore up and down. However, Rails 4+ features a helper...

When an AJAX request raises an exception on the server, Rails will show a minimal error page with only basic information. Because all Unpoly updates work using AJAX requests, you...

...show with full CSS and JavaScript. The code assumes you are using Ruby on Rails with better_errors, which is the default error view that modern Rails versions employ. If...

A Rails script lives in lib/scripts and is run with bin/rails runner lib/scripts/.... They are a simple tool to perform some one-time actions on your Rails application. A Rails...

...script has a few advantages over pasting some prepared code into a Rails console: Version control Part of the repository, so you can build on previous scripts for a similar...