Rails: Kill spring with fire

To ensure Spring is not running:

bin/spring stop
pkill -f spring

To prevent Spring from starting again:

export DISABLE_SPRING=1

Rails 4 introduced collection_check_boxes

Starting from Rails 4.0, you can use a special form options helper called #collection_check_boxes. It behaves similar to #collection_select, but instead of a single select field it renders a checkbox and a label for each item in the collection.

= form_for @post do |form|
  = form.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial

How generated form params look like
---------------------------------...

A short overview of common design patterns implemented within Rails

The linked content includes a few design patterns implemented with Ruby on Rails.

What is the card indented to achieve?

  • You can use the pattern names for code reviews, so all parties know with only a few words which change is requested. Example: "Please use a form object here"
  • You can learn about new code patterns
  • You should read the sections "Advantages of using design patterns" and "Disadvantages of using design patterns in a wrong way", since design patterns do not replace good code

Included Design Patterns: Service, Value objec...

Vortrag: Elasticsearch Grundlagen und Rails-Integration mit searchkick

Was ist Elastic?

  • Suchmaschine, basierend auf Apache Lucene
  • größtenteils Open-Source
  • einige kommerzielle Features ("Elastic Stack", früher "X-Pack")
    • Zugriffsrechte (bis vor kurzen)
    • Monitoring
    • Reporting
    • Graph-Unterstützung
    • Machine Learning
  • REST-Api (JSON über HTTP)

Grundlagen

Elastic antwortet per Default auf Port 9200

http GET :9200
{
  "name": "ntK2ZrY",
  "cluster_name": "elasticsearch",
  "cluster_uuid": "Bbc-ix5bQZij5vfFU29-Cw",
  "version": {
    "number": "6.7.1",
    "build_flavor": "...

Ruby on Rails: Finding a memory leak

The author describes his little journey in hunting down a memory leak. Maybe his approach and tooling may one day help you in a similar situation.

Tools: rbtrace, ObjectSpace.trace_object_allocations_start, heapy, sheap

Using Apache Benchmark (ab) on sites with authentication

Apache HTTP server benchmarking tool (ab) is a nice tool to test performance on sites delivered by HTTP. If the site you're about to test is placed behind a login, follow these steps to successfully use ab on it.

  1. Open the site to test in the browser of your choice. Do not login yet.
  2. Use developer tools to show all cookies used by the site. (Chrome: Ctrl+Shift+i, open the 'Resources' tab and click on the site below 'Cookies' on the left. Firefox: Right-click on the site, open 'We...

Use SSL for Amazon RDS / MySQL (and your Rails app)

In case you have sensitive data within your RDS instance, you want to use encrypted connections between your application and RDS instances. If you're using MySQL on RDS, here's what to do:

  1. Download the AWS CA file and copy it to the machine you want to connect from: http://s3.amazonaws.com/rds-downloads/mysql-ssl-ca-cert.pem
    As far as I could find out, you (currently) cannot access further details of the SSL configuration (such as public key).

  2. Try to connect using MySQL client

    `% mysql -uyour_username -p -h rds_hostname_from_...

Persist Rails or IRB Console Command History After Exit

Create, or edit your ~/.irbrc file to include:

require 'irb/ext/eval_history' # was 'irb/ext/save-history' for versions prior to Ruby 3.3
IRB.conf[:SAVE_HISTORY] = 2000
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-history"

Use different code for Rails 2 and Rails 3

When writing a piece of reusable code, you sometimes need to have separate code for Rails 2 and Rails 3. You can distinguish between Rails versions like this:

if Rails.version < '3' # mind the quotes
  # Rails 2 code goes here
else
  # Rails 3+ code goes here
end

Rails: Parsing a time in a desired timezone

Sometimes you want to have a time in a given timezone independent from you Rails timezone settings / system timezone. I usually have this use case in tests.

Example

Time.parse('2020-08-09 00:00') will return different results e.g. 2020-08-09 00:00:00 +0200 depending on the Rails timezone settings / system timezone. But in this example we always want to have the given time in UTC because that's what the API returns.

it 'returns a valid API response', vcr: true do
  expect(client.get('/users/1')).to have_attributes(
    name: 'So...

Rails: Rest API post-mortem analysis

This is a personal post-mortem analysis of a project that was mainly build to provide a REST API to mobile clients.

For the API backend we used the following components:

  • Active Model Serializer (AMS) to serializer our Active Record models to JSON.
  • JSON Schema to test the responses of our server.
  • SwaggerUI to document the API.

It worked

The concept worked really good. Here are two points that were extraordinary compared to normal Rails project with many UI components:

  • Having a Rails application, that has no UI components (only...

Dynamically uploading files to Rails with jQuery File Upload

Say we want …

  • to create a Gallery that has a name and has_many :images, which in turn have a caption
  • to offer the user a single form to create a gallery with any number of images
  • immediate uploads with a progress bar per image
  • a snappy UI

Enter jQuery File Upload. It's a mature library that can do the job frontend-wise. On the server, we'll use Carrierwave, because it's capable of caching images.

(FYI, [here's how to do the u...

Caching in Rails

The information in this card is only relevant for Rails 2.3-era apps.


This note gives a quick introduction into caching methods (page caching, action caching and fragment caching) in rails and describes some specific problems and solutions.

The descriptions below are valid for Rails 2 and 3. Recently, caching with timestamp- or content-based keys has become more popular which saves you the pain of invalidating stale caches.

How to enable/disable caching

To enable or disable caching in rails you ca...

Using mime types with send_file

When using send_file (for example for attachments of any kind), make sure your application knows the correct mime types so that all browsers can handle the files. It is much more convenient for users if they can decide to open a file directly instead of having to save it first.

For Rails >= 3.2

Simply put your mime types in config/initializers/mime_types.rb. send_file will take care of everything else.

For Rails < 3.2

Put your mime types in config/initializers/mime_types.rb. Additionally, tell send_file to use them (for ex...

Heads up: Rails offers two similar means for text truncation

Rails defines a #truncate helper as well as a method String#truncate.

= truncate("my string", length: 5)
= "my string".truncate(5)

Both are really similar; in fact, the helper invokes the method and improves it with two niceties: support for passing a block (which could e.g. render a "read on" link), and html_safe knowledge.

Prefer the truncate() helper

Warning: truncate() calls html_safe if you're not escaping. FWIW, an HTML string may easily become invalid when truncated, e.g. when a closing tag gets chopped off.
...

Upgrading Cucumber and Capybara to the latest versions available for Rails 2

Specify these gem versions in your Gemfile:

gem 'cucumber', '~> 1.3.0'
gem 'cucumber-rails', '= 0.3.2' # max version for Rails 2
gem 'capybara', '< 2' # capybara 2+ requires Rails 3
gem 'mime-types', '< 2' # dependeny of capybara
gem 'nokogiri', '< 1.6' # dependency of capybara
gem 'rubyzip', '< 1' # dependency of selenium-webdriver, rubyzip 1+ requires Ruby 1.9
gem 'cucumber_factory'
gem 'database_cleaner', '< 1'
gem 'cucumber_spinner', '~> 0.2.5'
gem 'launchy', '~> 2.1.2'

With these versions set, `...

How to include Sidekiq job IDs in Rails logs

When logging in Rails, you can use the log_tags configuration option to add extra information to each line, like :request_id or :subdomain. However, those are only valid inside a request context and have no effect when your application is logging from inside a Sidekiq process.
This includes custom as well as any framework logs, like query logging from ActiveRecord.

Since Sidekiq Workers run inside threads of a single process, running multiple jobs in...

Bundler for Rails 2.3.x

Update RubyGems and Passenger

Bundler requires Rubygems >= 1.3.6. Run gem update --system if you have an older version.
It also is not compatible with older versions of passenger, so bring that up to date as well (2.2.15 works).

If you installed RubyGems through apt (which you should never do!), you may see a message giving you a hint to use apt to update.
Some people advise to install the 'rubygems-update-1.3.7' gem on Ubuntu systems if you used apt to install RubyGems.
I did that - and lost all...

Rails logs are not flushed automatically (in Rake tasks)

The Rails logger will store its content in a buffer and write it into the file system every 1000 lines. This will come back to bite you when using Rails.logger.info to write log output during Rake tasks or on a production console.

You often won't notice this because for the development and test environments auto_flushing is set to write after each line. On production environments the Rails logger writes only every 1000 lines -- and not upon shell or script ter...

How to fix: WrongScopeError when using rspec_rails with Rails 6.1

tl;dr: Upgrade the gem to at least 4.0.1

When you use rspec_rails in a version < 4 with Rails 6.1 you may encounter an error like this:

Failure/Error:
  raise WrongScopeError,
    "`#{name}` is not available from within an example (e.g. an " \
    "`it` block) or from constructs that run in the scope of an " \
    "example (e.g. `before`, `let`, etc). It is only available " \
    "on an example group (e.g. a `describe` or `context` block)."
    `name` is not available from within an example (e.g. an `it` block) or from constructs that...

Running Rails 2 apps with modern MariaDB SQL server

You might have some trouble running a Rails LTS 2 app with MySQL 5.7.

If you don't want to hack Mysql 5.6 into your modern Ubuntu or use the MySQL sandbox, you might want to try MariaDB 10.x.

MariaDB 10.x should work with both old and new Rails applications.

[Switch to MariaDB](https://makandracards.com/makandra/468343-how-...

Rails routes: Extracting collection actions into their own controllers

Let's say you have two screens:

  1. Show a given project
  2. Show a report for all projects

Ideally you want both screens to be handled by different controllers like this:

GET /projects/:id        => ProjectsController#show
GET /projects/report     => Projects::ReportsController#show

What seems like a simple requirement is a little awkward to configure in your routes.
Obviously the report should be a singleton resource, but how can we nest it into the Projects:: namespace?

What does not work is this:

resources :proj...

How to fix: Rails query logs always show lib/active_record/log_subscriber.rb as source

Rails 5.2+ supports "verbose query logs" where it shows the source of a query in the application log.
Normally, it looks like this:

  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE ...
  ↳ app/controllers/users_controller.rb:42:in `load_users'

However, you may encounter ActiveRecord's LogSubscriber as the source for all/most queries which is not helpful at all:

  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE ...
  ↳ activerecord (6.0.3.3) lib/active_record/log_subscriber.rb:100:in `debug'

While th...

Downloading files from Ruby on Rails

To offer files for download, use send_file.

def download(file)
  send_file file.path, :disposition => 'attachment'
end

Note that a send_file replaces the default :render action.