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...

Since Rails 6.1, if we use where.not with multiple attributes, it applies logical NAND (NOT(A) OR NOT(B)) instead of NOR (NOT(A) AND NOT(B)). If you do...

...becomes "Don't send newsletters to trashed admins". User.where.not(role: 'admin', trashed: true) # Before Rails 6.1, with NOR => "SELECT "users".* FROM "users" WHERE "users"."role" != 'admin' AND "users"."trashed" != TRUE...

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...

api.rubyonrails.org

Rails offers a way to prepend (or append) view paths for the current request. This way, you can make the application use different view templates for just that request.

...action :prepare_views def index # ... end private def prepare_views if prepend_view_path Rails.root.join('app', 'views', 'special') end end end If is true, Rails will first look into app/views/special...

...to summarize by example the different uses of heredoc. In Ruby << vs. <<- vs. <<~ In Rails strip_heredoc vs. squish strip_heredoc should be used for a text, where you want...

Using heredoc for prettier Ruby code How to: Ruby heredoc without interpolation Rails 3+ def foo bar = <<-TEXT.strip_heredoc line1 line2 line3 TEXT puts bar.inspect end

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...

If you're suffering from a huge de.yml or similiar file, cry no more. Rails lets you freely organize your dictionary files in config/locales. My organization works like this: config/locales/rails.de.yml...

...modified Rails boilerplate config/locales/faker.de.yml modified Faker boilerplate config/locales/models.de.yml model names, attribute names, assignable_value labels config/locales/views.de.yml text in the GUI config/locales/blocks.de.yml if you organize your CSS with BEM you can...

...module structure. The typical example would be the concerns folder, which exists in new Rails applications by default and does not create a constant module Concerns. app ├── models    ├── concerns ├── shareable.rb...

...following official api: app ├── models    ├── shared ├── shareable.rb # Defines constant Shared::Shareable # e.g. in application.rb Rails.autoloaders.main.collapse("#{Rails.root}/app/models/shared") # with collapsed shared dir app ├── models    ├── shared ├── shareable.rb # Defines constant Shareable

guides.rubyonrails.org

...html_safe and translate them with = t('.text_html'). When you're localizing a Rails application, sometimes there is this urge to include a little HTML. Be it some localized...

...to learn more about &lt;em&gt;the corporation&lt;/em&gt;. Alright. Rails is being helpful here and saves you from accidentally injecting HTML into the page. But how...

Rails supports time zones, but there are several pitfalls. Most importantly because Time.now and Time.current are completely different things and code from gems might use one or the other.

...only about one time zone is a bit tricky. The following was tested on Rails 5.1 but should apply to Rails 4.2 as well. Using only local time

As your Rails project grows, you will accumulate a number of small patches. These will usually fix a bug in a gem, or add a method to core classes.

...change_storage.rb fix_cache_ids.rb sanitize_filename_characters.rb ruby/ range/ covers_range.rb array/ dump_to_excel.rb xss_aware_join.rb enumerable/ collect_hash.rb natural_sort.rb string/ to_sort_atoms.rb rails/ find_by_anything.rb form_builder.rb form_for_with_development_errors.rb Note how all patches for standard library classes are in the ruby...

makandra dev

Just found out about a great feature in Rails that seems to be around since Rails 2. Start a console with the --sandbox (or -s) parameter: rails console --sandbox

...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 AirBrake...

...under Selenium WebDriver is super-painful. It's much easier to detect the current Rails environment instead. You might be better of checking against the name of the current Rails...

...in a data-environment of your . E.g., in your application layout: <html data-environment=<%= Rails.env %>> Now you can say in a piece of Javascript: if (document.documentElement.dataset.environment == 'test') { // Code that should...

makandra dev

...a few minor exceptions for our Austrian friends. Luckily, the I18n gem used by Rails has a fallback feature where you can make one locale file fall back to another...

...is defined in the current locale (without fallback) Do this: I18n.exists?('my.key', fallback: false) Rails 2 For Rails 2.3.11 you need to upgrade your project to use the I18n gem...

This card describes how to install some tasks only for a given Rails environment or for a given Capistrano stage ("deployment target"). Installing jobs only for a given...

...Rails environment In your schedule.rb you may use environment variable to access the Rails environment of the current deployment: if environment == 'staging' every :day do # Setup job that will only...

Starting with Rails 7.1 the production logger is set to standard out. For applications running with opscomplete ensure to keep logging to a file as before (e.g. when running bin/rails...

...be enough to change these lines in the config/environments/production.rb back to the implementation in Rails <7.1: - # Log to STDOUT by default - config.logger = ActiveSupport::Logger.new(STDOUT) - .tap { |logger| logger.formatter = ::Logger::Formatter.new

makandra dev

Rails partials have a lot of "hidden" features and this card describes some non-obvious usages of Rails Partials. Rendering a basic partial The most basic way to render a...

To make sure that all developers use a compatible version of Node.js, your Rails project should declare the required Node.js in a file called .nvmrc. When a .nvmrc exists...

...asdf is sunsetting its support for LTS aliases. Testing compatibility In general, a recent Rails projects should use the currently active LTS version of LTS. If you are unsure about...

When you want to group rails models of a logical context, namespaces are your friend. However, if you have a lot of classes in the same namespace it might be...

'accounting_' end end class Accounting::Invoice < ApplicationRecord ... end class Accounting::Payment < ApplicationRecord ... end Rails will be able to derive the table name accounting_invoices for Accounting::Invoice...

Several Rails migration methods accept index: true as an option to create an index. In some cases (like #add_column), this option is silently discarded. Know what you are doing...

...positive" btree (positive) "index_examples_on_user_id" btree (user_id) So what happened? Rails created indexes for all fields that we added inside our create_table statement.

In the past we validate and set default values for boolean attributes in Rails and not the database itself. Reasons for this: Older Rails didn't support database defaults when...

An alternative approach, which currently reflects more the general opinion of the Rails upstream on constraints in the database, is adding default values in the schema of the...

Testing your responses in Rails allows to parse the body depending on the response MIME type with parsed_body. get '/posts.json' response.parsed_body # => [{'id' => 42, 'title' => 'Title'}, ...]

...drop JSON.parse(response.body) and replace it with parsed_body. There also exists a cop Rails/ResponseParsedBody that you can enable via rubocop-rails...

greg.molnar.io

Greg Molnar has written a neat article about creating a single-file Rails app. This is not meant for production use but can be useful to try things out, e.g...

...when hunting down a bug or embedding a Rails app into the tests of a gem. What you do is basically: Put everything (gems, application config, database migrations, models, controllers...