FactoryBot: Passing attributes to associated records using transient attributes

FactoryBot transient attributes can pass custom values into associated records, letting parent factories build children with dynamic names and flags.

Automatically build sprites with Lemonade

How it works

See the lemonade descriptions.

Unfortunately, the gem has a few problems:

  • it does not work with Sass2
  • it always generates all sprites when the sass file changes, which is too slow for big projects
  • it expects a folder structure quite different to our usual

All these problems are solved for us, in our own lemonade fork. This fork has since been merged to the original gem, maybe we can use t...

Why belongs_to/has_many cannot overwrite methods with the same name

ActiveRecord association macros do not replace existing instance methods with the same name, so custom methods can still shadow belongs_to and has_many accessors.

How to open files from better_errors with RubyMine on Linux

RubyMine rubymine:// links can fail on GNOME/Linux, blocking better_errors from opening source files in the editor. A custom desktop handler and BETTER_ERRORS_EDITOR_URL make file jumping work.

RSpec: Using helpers in view specs

View specs can crash on undefined helper methods; enabling config.action_controller.include_all_helpers or including helper modules makes view rendering work.

How to deal with "invalid %-encoding" error in application for malformed uri

Malformed request URIs can raise invalid %-encoding and break the app before routing. A middleware can return 400 Bad Request instead of ArgumentError or ActionController::BadRequest.

Whenever requires you to set the application attribute in the Capistrano config

Whenever needs application set in Capistrano so cron entries keep a stable identifier and do not accumulate duplicate jobs across deploys.

Debugging Webpacker config

Webpacker configuration can be hard to inspect when builds misbehave; dumping the environment, using browser or Node debugging, and emitting warnings help reveal the active webpack settings.

Speed up better_errors

Better Errors can become very slow in development when large objects are inspected and rendered. Limiting huge inspect output improves error-page performance.

Stop writing "require 'spec_helper'" in every spec

Configure .rspec to load spec_helper or rails_helper automatically, avoiding repeated require lines in every spec and making parallel test setups work with .rspec_parallel.

Deutsche Bahn: Show details of past rides

DB BAHN order numbers on credit card statements can be used to look up details of past rides on the Deutsche Bahn ticket portal.

Disable text-transforms in Selenium tests

text-transform: uppercase can make Selenium assertions flaky and break umlaut handling; disabling transforms in tests improves reliable label text matching.

Updated: Rails: Restrict deletion of a parent record using scoped associations

Scoped associations can block parent deletion when dependent records should remain valid; a cleaner callback setup and an example clarify the restriction.

Consul 0.4.0 released

Consul 0.4.0 adds temporary power switching, support for Ruby collections and arbitrary objects as powers, and drops the ActiveSupport::Memoizable dependency.

Preparing your test database: mind the differences

Test database setup can drift from development when schema dumps omit SQL-specific details; choose the right Rake task to keep structure, charset, and collation aligned.

Mysql::Error: BLOB/TEXT column can't have a default value

MySQL 5.6 rejects default values on BLOB and TEXT columns, blocking migrations that rely on them. Adjust the migration, move defaults into the application, or temporarily change sql_mode.

Capistrano task to tail remote application logs of multiple servers

Monitor logs across multiple app servers from one terminal and avoid missing per-host errors; LOG selects another file, and terminal line truncation can hide long entries.

How to make programming hard for yourself

For all of my professed admiration of Ruby on rails, I personally don't think that easier and more productive CRUD application writing will shake things up. I personally care very much about writing applications in a tenth of the time, but using Rails is like listening to Jaco Pastorius. The real learning experience comes when you try to duplicate the feat.

Working around the ancestry gem's way of object destruction

The ancestry gem allows you to easily use tree structures in your Rails application.

There is one somewhat unobvious pitfall to it: its way of applying the orphan_strategy which defines how it handles children of an object going to be destroyed.

What's this all about?

In many cases you might want to disallow destruction if there are any child nodes present. The restrict strategy does the trick but raises an exception when destroy is called:
has_ancestry :orphan_st...

Concurrent Tests

Install gem and plugin

sudo gem install parallel
script/plugin install git://github.com/grosser/parallel_tests.git

Adapt config/database.yml

test:
  database: xxx_test<%= ENV['TEST_ENV_NUMBER'] %>

Create test databases

script/dbconsole -p
CREATE DATABASE `xxx_test2`;
...

Generate RSpec files

script/generate rspec

(you'll probably only let it overwrite files in script/)

Prepare test databases...

Sudo a gem executable does not work on Ubuntu

sudo cannot find Ruby gem executables on Ubuntu because gem binaries live outside its secure path; symlinks, a different bindir, or changing secure_path work around it.

Be careful with "memoize"

ActiveSupport::Memoizable can return wrong results when a memoized method is called with arguments, because true may trigger recomputation instead of being passed through.

Spreewald: Old-school cucumber steps, freshly pickled

Spreewald keeps Cucumber-style web steps available while adding reusable steps for emails, tables and time travel in a Ruby gem.

Take care when merging with params

Be careful when using params.merge as params is a HashWithIndifferentAccess.

Why?

Usually this should not be an issue but it turns crazy if you try to include associated models deeper than 1 level:
options = params.merge(:include => { :user => :avatar })
Post.paginate options

When inspecting the merged params you will get something like this:
{ :include=> { "user" => :avatar }, :page => 23 }

Here the :user symbol in the hash of inclusions turned into a "user"...