How to fix routing error when using concerns in Rails up to 3.2.22.1

tl;dr

  • Don't write resources :people, :concerns => :trashable

  • Write

    resources :people do
      concerns :trashable
    end
    

Why

Writing a controller spec I encountered this error:

Failure/Error: get :index
ActionController::RoutingError:
  No route matches {:controller=>"people"}

caused by this route definition

resources :people, :concerns => :trashable

which renders strange routes:

      trash_person PUT    /people/:id/trash(.:format)             people#check {:concerns=>:trashable}
          ...

Capybara: Find the innermost DOM element that contains a given string

Let's say you want to find the element with the text hello in the following DOM tree:

<html>
  <body>
    <article>
      <strong>hello</strong>
      <strong>world</strong>
    </article>
  </body>
</html>

You might think of XPath's contain() function:

page.find(:xpath, ".//*[contains(text(), 'hello')")

Unfortunately that returns a lot more elements than you expect:

[ <html>...<html>,
  <body>...</body>,
  <article>...</article>,
  <strong>hello</strong> ]

What you need to do instead is to *find all...

Rails route namespacing (in different flavors)

TL;DR There are three dimensions you can control when scoping routes: path helpers, URL segments, and controller/view module.

scope module: 'module', path: 'url_prefix', as: 'path_helper_name' do
  resources :examples, only: :index
end

as → prefixes path helpers: path_helper_name_examples_path and path_helper_name_examples_url
path → prefixes URL segments: /url_prefix/examples
module → nests the controller: controller Module::ExamplesController, found at app/controllers/module/examples_controller.rb with views ...

Geordi 1.3 released

Changes:

  • Geordi is now (partially) tested with Cucumber. Yay!
  • geordi cucumber supports a new @solo tag. Scenarios tagged with @solo will be excluded from parallel runs, and run sequentially in a second run
  • Support for Capistrano 2 AND 3 (will deploy without :migrations on Capistrano 3)
  • Now requires a .firefox-version file to set up a test firefox. By default now uses the system Firefox/a test Chrome/whatever and doesn't print warnings any more.
  • geordi deploy --no-migrations (aliased -M): Deploy with `cap ...

WTF Opera Mini?!

In developing countries like Nigeria, Opera Mini is used by up to 70% of users on mobile.
This is a collection of front-end development features not supported by Opera Mini and, more importantly, some crowdsourced workarounds for them. This isn't about bashing the problem, but figuring out the solution.

Geordi 1.2 released

Changes:

  • Remove some old binaries (commands still exist in geordi) and mark others as deprecated
  • Rewrite deploy command to support most deploy scenarios:
    • master to production
    • feature branch to staging
    • master to staging or production to production (plain deploy)
  • Improve Cucumber command (fixes #18):
    • Fix pass-through of unknown options to Cucumber
    • Add --rerun=N option to rerun failed Cucumber tests up to N times. Reboots the test environment between runs, thus will pick up fixes you made durin...

Git: Keep your repository tidy

When you're using feature branches, they will stack up if you don't delete them after the merge to master. Here's how to tidy them up.

Delete feature branches

Find already-merged branches by running

# On branch master
git branch --merged

You may safely delete each of the listed branches, because they point to commits that are contained in the history of your current branch (i.e. master).

git branch -d my/feature-branch # Delete feature branch locally
git push origin :my/feature-branch # Push *nothi...

How to open a new tab with Selenium

Until recently, you could open a new tab via window.open when using execute_script in Selenium tests. It no longer works in Chrome (will show a "popup blocked" notification).

This is because browsers usually block window.open unless the user interacted with an element for security reasons. I am not sure why it did work via Selenium before.

Here is an approach that will insert a link into the page, and have Selenium click it:

path = "/your/path/here"
id = "helper_#{SecureRandom.hex(8)}"
execute_script <<-JAVASCRIPT
  ...

Make Nokogiri use system libxml2

The nokogiri gem provides different packages for several platforms. Each platform-specific variant ships pre-built binaries of libxml2, e.g. x86_64-linux includes binaries for 64bit Linux on Intel/AMD. This significantly speeds up installation of the gem, as Nokogiri no longer needs to compile libxml2.

However, this also means that for each security issue with libxml2, Nokogiri maintainers have to update their pre-built binaries and release a new version of the gem. Then, you need to update and ...

RSpec & Devise: How to sign in users in request specs

You know that Devise offers RSpec test helpers for controller specs. However, in request specs, they will not work.

Here is a solution for request specs, adapted from the Devise wiki. We will simply use Warden's test helpers -- you probably already load them for your Cucumber tests.

First, we define sign_in and sign_out methods. These will behave just like ...

You can now override all Spreewald steps with more specific versions

You can now define this step without Cucumber raising Cucumber::Ambiguous:

Then /^I should see "whatever I want"$/ do
  ...
end

This is available in Spreewald 1.5.0+.

Override Cucumber steps without an ambiguity error

Cucumber raises a Cucumber::Ambiguous if more than one step definitions match a step.

Our new cucumber_priority gem provides a way to mark step definitions as overridable, meaning that they can always be overshadowed by a more specific version without raising an error.

This gem is currently used by spreewald and cucumber_factory.

Marking step definiti...

Spreewald: Click on an element with a CSS selector

Spreewald 1.4.0 comes with this step:

When I click on the element ".sidebar"

We recommend to define a selector_for method in features/support/selectors.rb so you can refer to the selector in plain English:

When I click on the element for the sidebar

Defining and calling lambdas or procs (Ruby)

Ruby has the class Proc which encapsulates a "block of code". There are 2 "flavors" of Procs:

  • Those with "block semantics", called blocks or confusingly sometimes also procs
  • Those with "method semantics", called lambdas

lambdas

They behave like Ruby method definitions:

  • They are strict about their arguments.
  • return means "exit the lambda"

How to define a lambda

  1. With the lambda keyword

    test = lambda do |arg|
      puts arg
    end
    
  2. With the lambda literal -> (since Ruby 1.9.1)
    ...

Lazy-loading images

Note

This card does not reflect the current state of lazy loading technologies. The native lazy attribute could be used, which is supported by all major browsers since 2022.

Since images are magnitudes larger in file size than text (HTML, CSS, Javascript) is, loading the images of a large web page takes a significant amount of the total load time. When your internet connection is good, this is usually not an issue. However, users with limited bandwidth (i.e. on mobile) need to mine their data budget...

PostgreSQL: Expanded display and other command line features

One useful postgres command I stumbled upon recently was \x. It gives you an expanded display which allows you to actually read the results of your select * from queries. The link below describes a few more useful techniques and commands.

About Ruby's conversion method pairs

Ruby has a set of methods to convert an object to another representation. Most of them come in explicit and implicit flavor.

explicit implicit
to_a to_ary
to_h to_hash
to_s to_str
to_i to_int

There may be even more.

Don't name your methods like the implicit version (most prominently to_hash) but the like the explicit one.

Explicit conversion

Explicit conversion happens when requesting it, e.g. with the splat opera...

A case for Redactor

Redactor is yet another WYSIWYG editor. It definitely has its weak points, but I want to point out that it has clear strengths, too.

Pro

  • Simple and beautiful interface.
  • Outstandingly organized source code. Have never seen a JS library that was this structured.
  • Clear, comprehensive and searchable API documentation. Filled with code examples.
  • Easily customizable: specify toolbar buttons, pass various callbacks, etc.
  • Features a collection of great [plugins](ht...

Heads up: Ruby implicitly converts a hash to keyword arguments

When a method has keyword arguments, Ruby offers implicit conversion of a Hash argument into keyword arguments. This conversion is performed by calling to_hash on the last argument to that method, before assigning optional arguments. If to_hash returns an instance of Hash, the hash is taken as keyword arguments to that method.

Iss...

Recommended Git workflow for feature branches

This is a guide on how to effectively use Git when working on a feature branch. It is designed to get out of your way as much as possible while you work, and ensure you end up with clean commits in the end.

We assume you are the only person working on this branch. We also assume the branch has never been "partially" merged into master.

You want to start a feature branch

git checkout master
git checkout -b my-feature-branch
git push -u origin my-feature-branch

You've added code that works ind...

pgAdmin has a "graphical EXPLAIN" feature

When working with PostgreSQL, you can use pgAdmin as a GUI.
While you can do most things just like on an SQL console, you can use it to display EXPLAIN results in a more human-readable way.


(image from the Postgres manual)

  1. Open up pgAdmin, connect to your server
  2. Pick a database from the left pane
  3. Click the "SQL" icon in the toolbar, or press Ctrl+E to open the query tool.
  4. Paste any queries that you'd like to explain.
  5. Go to "Query" → "Explain analyze", or ...

Rarely say yes to feature requests

A fantastic guide for a dilemma facing any web-based product.

Here’s a simple set of Yes/No questions that you can quickly answer before you add another item to your product roadmap.

Saying yes to a feature request – whether it’s a to an existing customer, a product enquiry, a teammate, or a manager – is immediately rewarding. It’s an unspoken transaction where you barter long term product focus in exchange for short term satisfaction. Buying short term joy for the cost of long term pain is the human condition.

  1. Does it fit your ...

Improving browser rendering performance

As the web is being used for more and more tasks, expectations rise. Not only should web pages offer rich interaction, they must be responsive in both size and interaction.

This imposes a paradoxon that needs to be solved by building performing applications. It's not enough any more to have your web site do crazy stuff, it is also required to do it crazy fast. This card is intended to give you an introduction to this emerging aspect of web development.

Read this introductory [performance study on Pinterest](http://www.smashingmagazine.com/...

httpclient: A Ruby HTTP client for serious business

While debugging an intricate issue with failed HTTP requests I have come to appreciate the more advanced features of the httpclient Rubygem.

The gem is much more than a lightweight wrapper around Ruby's net/http. In particular:

  • A single HTTPClient instance can re-use persistent connections across threads in a thread-safe way.
  • Has a custom and configurable SSL certificate store (which you probably want to disable by default...