View
Auto-destruct in 37 days

Updated: Rails: When defining scopes with class methods, don't use `self`

This issue is back in Rails 5. Un-deprecated and re-repeated the card.

Repeats

Browsers will not send a referrer when linking from HTTPS to HTTP

  • When your site is on HTTPS and you are linking or redirecting to a HTTP site, the browser will not send a referrer.
  • This means the target site will see your traffic as "direct traffic", i.e. they cannot distinguish such hits from a user who directly typed in the URL.

Reasons for this behavior

It's probably because of this RFC:

Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferr…

Repeats

Don't use the || operator to set defaults

I often see the use of || to set a default value for a variable that might be nil, null or undefined.

x = x || 'default-value'

This pattern should be avoided in all languages.

While using || works as intended when x is null or an actual object, it also sets the default value for other falsy values, such as false. false is a non-blank value that you never want to override with a default.

To make it worse, languages like JavaScript or Perl have [many more fal…

Repeats

Cucumber: Clear localStorage after each scenario

Capybara clears cookies before each scenario, but not other client-side data stores. If your app is using localStorage or sessionStorage, contents will bleed into the next scenario.

Use this hook to remove all site data after each scenario:

After do
  if Capybara.current_driver == :selenium && !Capybara.current_url.starts_with?('data:')
    page.execute_script <<-JAVASCRIPT
      localStorage.clear();
      sessionStorage.clear();
    JAVASCRIPT
  end
end

ActiveRecord::RecordNotFound errors allow you to query the :name and :id of the model that could not be found

ActiveRecord::RecordNotFound errors provide quite meaningful error messages that can provide some insight on application details. Consider the following:

ActiveRecord::RecordNotFound: Couldn't find Organisation::Membership with 'id'=12 [WHERE "organisation_memberships"."user_id" = 1]

You should probably not simply render those error messages to the user directly. Instead you you might want to re-raise your own errors. ActiveRecord::RecordNotFound provides you with methods :model and :id where you can get information about w…

Auto-destruct in 32 days

Updated: LoDash: isBlank and isPresent mixins

_.isBlank now returns false for all functions and for boolean values.

Repeats

Fun with Ruby: Returning in blocks "overwrites" outside return values

In a nutshell: return statements inside blocks cause a method's return value to change. This is by design (and probably not even new to you, see below) – but can be a problem, for example for the capture method of Rails.


Consider these methods:

def stuff
  puts 'yielding...'
  yield
  puts 'yielded.'
  true
end

We can call our stuff method with a block to yield. It works like this:

>> stuff { puts 'hi!' }
yielding...
hi!
yielded.
=> true

So the block is yielded a…

IRB: last return value

In the ruby shell (IRB) and rails console the return value of the previous command is saved in _ (underscore). This might come in handy if you forgot to save the value to a variable and further want to use it.

Example:

irb(main):001:0> 1 + 2
=> 3
irb(main):002:0> _
=> 3
irb(main):003:0> a = _
=> 3

RSpec's hash_including matcher does not support nesting

You can not use the hash_including argument matcher with a nested hash:

describe 'user' do
  let(:user) { {id: 1, name: 'Foo', thread: {id: 1, title: 'Bar'} }

  it do 
    expect(user).to match(
      hash_including(
        id: 1, thread: {id: 1}
      )
    )
  end
end  

The example will fail and returns a not very helpful error message:

```
expected {:id => 1, :name => "Foo", :thread => {:id => 1, :title => "Bar"}} to inc…

Repeats

How to solve Selenium focus issues

Selenium cannot reliably control a browser when its window is not in focus, or when you accidentally interact with the browser frame. This will result in flickering tests, which are "randomly" red and green. In fact, this behavior is not random at all and completely depends on whether or not the browser window had focus at the time.

This card will give you a better understanding of Selenium focus issues, and what you can do to get your test suite stable again.

Preventing accidental interaction with the Selenium window ——————–…

Auto-destruct in 29 days

Updated: How to set the user agent in tests

Changed from Rails 4 on to be request.headers['X-Api-Key'] instead of request.env['X-Api-Key']

Rails: Configure ActionController to raise when strong params are invalid

Put the line below in the respective env.rb file to make your action controllers raise an ActionController::UnpermittedParameters error when strong params are not valid. This might come in handy when you are implementing an API and you want to let the user know that the request structure was invalid. You can then rescue those errors by implementing a rescue_from to have a generic handling of those cases. Note that you might need to whitelist common params such as :format to not raise on valid requests.

```
config.action_controller.a…

External content

ActiveRecord: How to use ActiveRecord standalone within a Ruby script

Re-creating a complex ActiveRecord scenario quickly without setting up a full-blown Rails app can come in handy e.g. when trying to replicate a presumed bug in ActiveRecord with a small script.

```
# Based on http://www.jonathanleighton.com/articles/2011/awesome-active-record-bug-reports/

Run this script with $ ruby my_script.rb

require 'sqlite3'
require 'active_record'

Use binding.pry anywhere in this script for easy debugging

require 'pry'

Connect to an in-memory sqlite3 database

ActiveRecord::Base.establish_connection(
ad…

ImageMagick: How to auto-crop and/or resize an image into a box

Auto-cropping

ImageMagick can automatically crop surrounding transparent pixels from an image:

convert input.png -trim +repage output.png

You need to +repage to update the image's canvas, or applications will be randomly confused.
Trimming specific colors is also possible, see the documentation.

Resizing into a box

Occasionally, you want to resize an image to a maximum width or height, and change the "outer" image dimensions to something that won't match the input image.

To re…

Guide: How to use our (maybe in future) default rubocop config

Add a file .rubocop.yml with the following content in your $HOME path.

inherit_from:
  - https://raw.githubusercontent.com/makandra/rubocop-config/master/disabled.yml
  - https://raw.githubusercontent.com/makandra/rubocop-config/master/enabled.yml
  - https://raw.githubusercontent.com/makandra/rubocop-config/master/default.yml

PRs at makandra/rubocop-config are welcome. Also check the issue tracker.

RubyMine

Since version [201…

Know what makes your browser pant

I figure we needed a definitive reference for what work is triggered by changing various CSS properties. It's something I get asked about often enough by developers, and while we can do tests with DevTools, I have both the time and inclination to shortcut that for everyone. I'm nice like that. —Paul Lewis

Rails: wrap_parameters for your API

Rails 5 (don't know about the others) comes with an initializer wrap_parameters.rb. Here you can tell rails to wrap parameters send to your controllers for specific formats into a root node which it guesses from the controller name.

ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json]
end

This would wrap a flat json body, like

{"name": "Konata"}

that gets send to your UsersController into

{"name" => "Konata", "user" => {"name" => "Konata"}}

Note that the params are now duplicat…

Auto-destruct in 25 days

Updated: Render a view from a model in Rails

In Rails 5 you can say:

ApplicationController.render(
  :template => 'users/index',
  :layout => 'my_layout',
  :assigns => { users: @users }
)

If a Request Environment is needed you can set attributes default attributes or initialize a new renderer in an explicit way (e.g. if you want to use users_url in the template):

ApplicationController.renderer.defaults # =>
{
  http_host: 'example.org',
  https:      false,
  ...
}

``` …

View
3342 cards