View
Repeats

Operators "in" and "of" are very inconsistent between CoffeeScript and JavaScript

CoffeeScript and JavaScript (ECMAScript) both have operators in and of. Each language use them for more than one purpose. There is not a single case where the same operator can be used for the same purpose in both languages.

Check if an object (or its prototype) has a property

CoffeeScript

var hasFoo = 'foo' of object

JavaScript

var hasFoo = 'foo' in object;

Iterate through all properties of an object
================================…

Writing Code Comments

Code comments allow for adding human readable text right next to the code: notes for other developers, and for your future self.

As always, with great power comes great responsibility. Code comments can go wrong in many ways: they may become outdated, silently move away from the code they're referring to, restate the obvious, or just clutter files.

Good Comments

Here are some simple rules to keep your comments helpful:

Avoid stating what some code does – prefer the Why
Some say, perfect code would not need a single comment. That'…
Linked contentAuto-destruct in 54 days

Updated: Ruby constant lookup: The good, the bad and the ugly

I updated the ugly part to include the reason for a wrong constant lookup in production.

Repeats

Popular mistakes when using nested forms

Here are some popular mistakes when using nested forms:

  • You are using fields_for instead of form.fields_for.
  • You forgot to use accepts_nested_attributes in the containing model. Rails won't complain, but nothing will work. In particular, nested_form.object will be nil.
  • The :reject_if option lambda in your accepts_nested_attributes call is defined incorrectly. Raise the attributes hash given to your :reject_if lambda to see if it looks like you expect.
  • If you are nesting forms into nested forms, each model involved ne…
Repeats

Carrierwave: Deleting files outside of forms

TL;DR Use the #remove_<mounted_attribute>! method to delete attachments. Also, save the record after removing the file!


As you know, Carrierwave file attachments work by mounting an Uploader class to an attribute of the model. Though the database field holds the file name as string, calling the attribute will always return the uploader, no matter if a file is attached or not. (Side note: use #present? on the uploader to check if the file exists.)

class User < ApplicationRecord
  mount :avatar, AvatarUploader
end

Linked contentRepeats

Writing a README for a project

Rails applications and ruby gems should have a README that gives the reader a quick overview of the project. Its size will vary as projects differ in complexity, but there should always be some introductory prose for a developer to read when starting on it.

Purpose

That's already the main purpose of a project README: Give a new developer a quick overview of the project. In sketching this outline, the README should notify the reader of any peculiarity he needs to know of.

Remember that in a few months, you'll be a kind of "new …

Linked content

Heads up: Ruby's Net::HTTP silently retries a failing request

Ruby's Net::HTTP library repeats a failing request once, as long as it deems it idempotent (GET, HEAD etc). Both requests will use the configured timeout. Hence, if both requests time out, Net::HTTP will only return after twice the configured timeout.

This can become an issue if you rely on the timeout to strike precisely.

Repeats

Whitelist Carrierwave attributes correctly

Say you have a User with a Carrierwave attribute #avatar:

class User < ActiveRecord::Base
  mount_uploader :avatar, AvatarUploader
end

When whitelisting the avatar field in the controller, you might do this:

  params[:user].permit(:avatar)

But you probably want this:

  params[:user].permit(:avatar, :avatar_cache, :remove_avatar)

In this example:

  • :avatar_cache allows a newly upload image to persist through form roundtrips in the case of validation errors (something that isn't possible with Paper…
Repeats

Obtain pessimistic row locks on ActiveRecord objects

When requests arrive at the application servers simultaneously, weird things can happen. Sometimes, this can also happen if a user double-clicks on a button, for example.

This often leads to problems, as two object instances are modified in parallel maybe by different code and one of the requests writes the results to the database.

In case you want to make sure that only one of the requests "wins", i.e. one of the requests is fully executed and completed while the other one at least has to wait for the first request to be completed, you ha…

Quick HTML testing with RubyMine

If you need to test some HTML, e.g. an embed code, you can use RubyMine's "scratch files":

  1. File > New Scratch File (or Ctrl + Shift + Alt + Ins)
  2. Select "HTML" as file type
  3. Write or paste the HTML
  4. Move your mouse to the upper right corner of the scratch file editor. Pick a browser to instantly open your file.
Repeats

ActiveRecord: Specifying conditions on an associated table

We can use ActiveRecord's where to add conditions to a relation. But sometimes our condition is not on the model itself, but on an associated model. This card explains multiple ways to express this condition using ActiveRecord's query interface (without writing SQL).

As an example we will use a User that has many Posts:

```ruby
class User < ApplicationRecord
has_many :posts
scope :active, -> { tra…

Linked contentRepeats

Rails: Overriding view templates under certain conditions only

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.

Example

A use case of this is a different set of view templates that should be used under certain circumstances:

```
class UsersController < ApplicationController

before_action :prepare_views

def index

end

private

def prepare_views
if prepend_view_path Rails.root.join('app', 'views', 'special') end end

end …

Ruby: How to fetch a remote host's TLS certificate

TLS/SSL certificates are often used for HTTPS traffic. Occasionally a service may also use their TLS certificate to support public-key encrypting data (e.g. when it is part of the URI and visible to the user, but contains sensitive information).

Here is how to easily fetch such certificate data.

certificate = Net::HTTP.start('example.com', 443, use_ssl: true) { |http| http.peer_cert }
# => #<OpenSSL::X509::Certificate: subject=#<OpenSSL::X509::Name CN=www.example.org,...>

certificate.public_key
# => #<OpenSSL::PKey::RSA:0x...
Linked contentAuto-destruct in 26 days

Updated: How to write modular code

Restructured a bit and added a section about writing more classes.

Linked content

Inspecting a live Ruby process

How to get a backtrace from a running ruby process:

Repeats

Escape a string for transportation in a URL

To safely transport an arbitrary string within a URL, you need to percent-encode characters that have a particular meaning in URLs, like & or =.

If you are using Rails URL helpers like movies_path(:query => ARBITRARY_STRING_HERE), Rails will take care of the encoding for you. If you are building URLs manually, you need to follow this guide.

Ruby

In Ruby, use CGI.escape:

CGI.escape('foo=foo&bar=bar')
=> "foo%3Dfoo%26bar%3Dbar"

Do not ever use URI.encode or …

Linked content

Guide to String Encoding in Ruby

The linked article has a great explanation how to to deal with string encodings in Ruby. Furthermore you can check out some of our cards about encoding:

Repeats

How to write modular code

Or: How to avoid and refactor spaghetti code

Please note that I tried to keep the examples small. The effects of the methods in this card are of course much more significant with real / more complex code.

What are the benefits of more modular code?

Code is written once but read often (by your future self and other developers who have to understand it in order to make changes for example). With more modular code you reduce the scope of what has to be understood in order to change something. Also, naming things gives you the opportunity t…

This website uses cookies to improve usability and analyze traffic.
Accept or learn more