Today I Learned

September 15, 2020

I’ve been building a system that imports a lot of records from another system. The items from the other system have stable identifiers, but many other attributes will change.

In the past I’ve handled this scenario by iterating on each record, and individually “upsetting” into the local database. It would look something like

entries =
entries.each do |entry|
  attributes = entry_attributes_from_remote_system(entry)
  Entry.find_or_initialize_by(identifier: attributes.fetch("identifier").update(attributes)

This works fine and good, but I learned there’s a better way! Rails 6 introduced upsert_all. With this new method, many round trips to the database are replaced with one command.

entries =
entries_attributes = { |entry| entry_attributes_from_remote_system(entry) }
Entry.upsert_all(entries_attributes, unique_by: %w[identifier])

The one gotcha I’ve found so far, is that it fails if entries_attributes is an empty array. Easily mitigated with a presence check.

Entry.upsert_all(entries_attributes, unique_by: %w[identifier]) unless entries_attributes.blank?

The Big Binary blog post has a lot of great information on usage.

September 9, 2020

I needed to rebuild some git history today. It’s never a fun task.

What I found while doing it, is that I was losing merge commits. I found this out to late, after taking a much less efficient approach. But if I ever encounter this problem in the future, the --keep-empty flag will be helpful. As in

git rebase -interactive --keep-empty upstream

September 4, 2020

I built a Rails mailer for the first time in a very long time today. Revisiting the docs, I was greeted with a signature I didn’t recall from the past.

Mailer.with(some: "params", set: "this way").email_name.deliver_later

In the past, I’d always invoked mailers with

Mailer.email_name(some: "params", set: "this way").deliver_later

The with message feels very aligned with ActiveJob.set. For things that are needed on all mailers, like the recipient, I like standardizing on this approach for communicating params into the mailer.

August 31, 2020

Rails.env.test? is always preferable to writing Rails.env == "test". The behavior that powers this predicate method is the ActiveSupport::StringInquirer class.

This is not new information. But what was new, is finding the .inquiry method that is added to a whole bunch of objects, including strings and arrays..

%w[this that other].inquiry.other?


August 26, 2020

Thanks to my partner in code, I learned that you can change the character that begins a comment in a Git commit message.

From the docs:

Commands such as commit and tag that let you edit messages consider a line that begins with this character commented, and removes them after the editor returns (default #).

If set to “auto”, git-commit would select a character that is not the beginning character of any line in existing commit messages.

I’m often writing Markdown in my commit messages, to leverage their legibility in other contexts. Before this configuration, headings were off limits. Now that I’ve changed my configuration with git config --global core.commandChar ";", they’re gonna be all over the place.

June 27, 2020

A byte order mark is an optional character that may appear at the beginning of a text stream. The unicode character U+FEFF can be used to signal several things to a program reading the text.

My program reading the text is Ruby’s JSON.parse. The text being read a JSON payload from the Pinboard API.

A helpful email exchange with Pinboard support is what pointed me in the right direction. A recent server upgrade began inserting the byte order mark where it wasn’t present before. It sounds like this insertion is going to be removed, because it makes the raw JSON payloads un-parsable by JSON.parse in both Ruby and JavaScript.

In the meantime, I wanted to get my parsing fixed, so I could keep my Pinboard powered links up-to-date. With the tip from Pinboard support and some StackOverflow I got my JSON parsing fixed.

  def load_remote_json
    uri = URI("{auth_token}")
    body = Net::HTTP.get(uri)
+   body = strip_byte_order_mark(body)

+ def strip_byte_order_mark(potentially_unparsable)
+   potentially_unparsable.dup.sub("\xEF\xBB\xBF".force_encoding("UTF-8"), "")
+ end

This experience highlighted the tradeoffs of using vcr for tests. On the positive side, I had a cassette recording that captured the old API response. This allowed me to diff the old response and the new response to dig down and find what changed. On the negative side, I didn’t encounter the failure in parsing until it broke my link importing in production.


January 13, 2020

Needing to reduce a pathname into the filename without it’s extension is something I need to do often. But not too often. Just often enough to forget how I last did it, and clobber together a solution anew.

So this time I’m writing down the briefest solution I’ve found in Ruby, in hopes that it’ll commit to my memory.

require "pathname"
pathname ="~/some/path/to/the/mountains.jpg")
pathname.basename(pathname.extname).to_s # => "mountains"

Pathname is a great tool in the standard library.

January 7, 2020

Sometimes you install one gem.

gem install bundler

Sometimes you install it with a specific version.

gem install bundler -v "2.0.2"

Sometimes you install multiple gems.

gem install bundler minitest

But what do you do if you need to install multiple gems with specific versions? It is possible with a special syntax!

gem install "bundler:2.0.2" "minitest:5.13.0"

January 6, 2020

Something I really like from React Native is the global variable __DEV__. Being able to do things only in the development environment is quite handy. This concept is not unique to React Native, but that’s where I was introduced to it.

I’ve found myself in need of a similar strategy while building this static site in Rails. I have some dynamic interactions that I can use to curate content on my own machine, but I don’t want those scripts bloating the static build that is deployed to production.

This can be achived in Rails with webpacker using Webpack’s DefinePlugin!

// config/webpacker/environment.js
const { environment } = require("@rails/webpacker")
const webpack = require("webpack")

  new webpack.DefinePlugin({
    STATIC: process.env.NODE_ENV === "production",

module.exports = environment

October 16, 2019

Rails 6 introduces a new auto loader called zeitwork. The literature has me convinced transitioning to this new loader will be worth the effort. The legacy of the Rails apps we’ve built has us opting for the :classic loader in the immediate.

A nice thing about using :classic, is that Rails provides some deprecations that point toward getting ready for :zeitwork. As an example, autoloading constants in an initializer (config/initializers/[something].rb) emits a deprecation warning in Rails 6.

DEPRECATION WARNING: Initialization autoloaded the constants Sortable, Foldable, and Launderable.

Being able to do this is deprecated. Autoloading during initialization is going to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during initialization does not run again. So, if you reload Sortable, for example, the expected changes won't be reflected in that stale Class object.

`config.autoloader` is set to `classic`. These autoloaded constants would have been unloaded if `config.autoloader` had been set to `:zeitwerk`.

Please, check the "Autoloading and Reloading Constants" guide for solutions.

Following the Autoloading and Reloading Constants guide, and some supplementary Duck Duck Go’ing, I learned about the Rails.configuration.to_prepare API. Where initializers run once when the app is booting, blocks passed to to_prepare will be run before every request in development, and once before eager loading in production.

For a handful of constants that are being autoloaded in an initializer, using to_prepare did the trick.

-ActiveRecord::Base.send :include, Sortable
+Rails.configuration.to_prepare { ActiveRecord::Base.send :include, Sortable }

October 3, 2019

I’m intentionally slow to script things away in my day-to-day development. I understand the benefits of scripting away repetitive tasks. But I’ve found that they come at the cost of empathy.

I used to have an alias of be for running bundle exec. When I’d pair with newer developers, they’d begin to think that be is a command they should know, when in fact it was a customization they’d need to borrow. So I’ve formed the habit of always typing out bundle exec.

It takes a little more time. But when someone is looking over my shoulder, they’re learning how to do do the thing rather than learning my abstraction about how to do the thing.

September 27, 2019

While authoring a very boring HTML form I learned that you do not need a for/id pair on a label that is wrapping a radio input.

-<label for="radio_option_1">
-  <input id="radio_option_1" type="radio" name="cheese" value="cheddar"> Cheddar
+  <input type="radio" name="cheese" value="cheddar"> Cheddar

September 26, 2019

React Native’s <StatusBar /> component behaves similarly to <Helmet /> from react-helmet. Render them anywhere in the tree. Every time an element is rendered, it’s props get pushed onto the top of a stack that will reconcile as a cascade of props for imperatively updating outside values.

The source of StatusBar.js was particularly helpful, because I discovered it just as I was arriving at a near-identical solution for doing something similar in an app I’m working on.

September 18, 2019

git rebase --exec is a handy tool for ensuring that each commit is keeping the tests passing.

Ensuring that each commit keeps the tests passing is in service of an ideal I’ve been pursuing. I don’t like submitting commits with the phrase “fix tests” in the description. I like refactoring old functionality or introducing new functionality under green tests.

To do this, I tend to work in two phases lately.

Phase one is an exploratory branch where I’m figuring things out. This is me thrashing through the jungle with a machete.

Phase two is a refined branch, where I’m communicating to others what I figured out. This is more surgical with detailed commits, explaning what changed, why, and alternatives that were considered in my exploratory thrashing branch.

Before submitting phase two for consideration, I’m starting to get in the habit of making sure the tests passed each step of the way.

$ git rebase --exec "bin/rails test" master

That will run the Rails tests on every commit that contributed to the current branch.

August 19, 2019

React’s Developer Tools are accessible from Safari!

For the last three years I’ve been developing day-to-day in Safari. Whenver this practice comes up in conversation the first question is “what about React Developer Tools?” Until today my answer was to drop into Chrome.

Today I discovered that react-devtools can be launched as a standalone application that can be connected to.

I wired this up in my Rails app with some development only logic.

<% # app/views/application.html.erb %>
<% if Rails.env.development? && ENV["CONNECT_TO_REACT_DEVTOOLS"] == "yep" %>
  <%= javascript_include_tag "http://localhost:8097" %>
<% end %>

With this in place, starting a Rails server with the appropriate environment flag does the trick. bin/rails server CONNECT_TO_REACT_DEVTOOLS=yep

August 1, 2019

Updating for security vulnerabilities with yarn can be tricky. For example, I got a Github warning that my version of js-yaml needed to be updated. js-yaml does not appear in my package.json. It is one of my dependencies’ dependencies.

yarn update js-yaml@secure-version adds js-yaml into my dependencies, which is not what I want to communicate to the team.

Trying to solve for this communication problem brought me to Yarn’s selective dependency resolutions. This seems to fit the exact bill of what I’m trying to achieve. Among the reason’s to use selective dependency resolution is listed:

A sub-dependency of your project got an important security update and you don’t want to wait for your direct-dependency to issue a minimum version update.

Force yarn.lock to update appropriately, without communicating to a future maintainer that this is actually a dependency of our app. Works on my machine.

January 11, 2019

Use date.to_s(:db) when you need to use a date in a Rails YAML fixture. My muscle memory reached for date.format(:db), but that’s wrong. It’s .to_s

  last_wanted_cookies_at: <%= 1.second.ago.to_s(:db) %>

October 15, 2018

When testing ActiveJob, jobs performed with SomeJob.perform_now will not show up in the performed_jobs test helper method.

August 30, 2018

Today I was attempting to validate that three variables all held the same value. My clever approach was:

a = 1
b = 1
c = nil

[a, b, c]

I expected that to return false. It was returning true.


Showing my reasoning, elementary math style:

[a, b, c]

# becomes =>

[1, 1, nil]

# becomes =>

[1, nil].one?

There are two values, right? Here’s my mistake. In my quest for object-oriented-message-sending-purity I interpreted one? to be about the size of the array. But reading the docs, I’m reminded it’s not a message about the size of the array. It’s a message that passes each item in the array to a block, and returns true if exactly one of those return values is truthy. Without an explicit block, the implicit block is the element itself. 1 is truty. nil is not, so yes, there is one truthy value.

What I really wanted is [1, nil].count == 1. In the end, I reverted to some obvious as day boolean logic of a == b && b == c

I’m glad I wrote a test for something so small, because this particular error in this particular place would have led to a substantial security hole.

Lesson learned: just because there’s a nicely named message that sounds right doesn’t mean it’s the message I want to send. Also, quit trying to be clever.

July 11, 2018

At some point in time Rails added a nicety to ActionMailer that I’ve really appreciated. The nicety I mention is that an html formatted email will be automatically translated into a plaintext email counterpart that is not perfect, but passable when iterating on a blossoming application.

As our applications mature we’re upping our efforts on accessibilty. Within that effort, the automatically generated plaintext emails are being replaced by artisinal plaintext emails.

We’re good about writing tests, but our tests broke when we moved from providing the single part to providing multiple parts.

Today I rel-learned how to get to the different parts of the email when they’re being provided explicitly.

-assert_includes email.body.encoded, "some expected text"
+assert_includes email.html_part.body, "some expected text"
+assert_includes email.text_part.body, "some expected text"

Thanks again Stackoverflow.

May 30, 2017

Ruby’s defined? method is useful, but the syntax is a little surprising at first glance!

# These two are similar, but you call them different
defined? @whatever # call with the actual identifier
instance_variable_defined? :@whatever # call with a symbol of the identifier

defined? returns a string of what identifier is. In this case, nil or "instance-variable".

instance_variable_defined? returns a bool.

When nil is an acceptable memoized value, I often reach for a pattern of.

def whatever
  return @whatever if instance_variable_defined? :@whatever
  @whatever = some_expensive_computation

For tersness that communicates just as much, this could become

def whatever
  return @whatever if defined? @whatever
  @whatever = some_expensive_computation

August 31, 2016

Today I needed to re-raise an error in ruby, but change the error message slightly. It turns out this is baked right in to the use of raise!

  # something that raises
rescue => e
  raise e, "This is my modified message"

The docs!

May 3, 2016

import statements can be picky When using ES2015. With the variety of Babel plugins and configurations it’s easy to have some technically invalid syntax that compiles just fine in that configuration.

// family.js
export default {
  george: "Grandpa",
  michael: "Dad",
  maeby: "Cousin",

// uses_family.js
import { maeby } from "./family.js"

I don’t know what plugin I was relying on but previously this import statement worked. It turns out that destructuring off a default export is not actually a thing.

Option 1:

// family.js
export const george = "Grandpa"
export const michael = "Dad"
export const maeby = "Cousin"
export default { george, michael, maeby }

// uses_family.js
import { maeby } from "./family.js"

Option 2:

// family.js
export default {
  george: "Grandpa",
  michael: "Dad",
  maeby: "Cousin",

// uses_family.js
import Family from "./family.js"
const { maeby } = Family

March 9, 2016

Rails will save associations by default. If you build an in-memory representation of a record that’s not intended to be saved with a call to update you need to do one of two things.

  1. Set autosave to false. Example: has_one :other_thing autosave: false.
  2. Don’t associate the built record with the object you’re saving

This default behavior manifested itself because I was doing something of the form:

class Thing
  has_one :other_thing # 1. Use autosave: false

  def optimistic_version_of_other_thing self) # 2. don't associate the record with self

thing = Thing.last
thing.optimistic_version_of_other # I don't want this persisted
thing.update(anything: "else")

January 27, 2016

I’m almost always wanting to add configuration hooks to Rails engines when I build them. Up to this point I’ve never taken the time to figure out the most succinct way to provide configuration hooks. It turns out that it’s much simpler than I even imagined.

module MyGem
  class Engine < ::Rails::Engine
    isolate_namespace MyGem

    config.my_gem =
    config.my_gem.some_setting = true

That’s it! Setting config directly in the class definition will expose the configuration in the consuming Rails application.

January 7, 2016

Today I re-learned about ActionController::TestCase. It’s pretty common to send the request parameters in as the second argument. What I always forget is that the third and fourth parameters represent the session and the flash respectively.

test "something that depends on the session and the flash" do
  post :create, { always: "money" }, { in: "the" }, { banana: "stand" }
  assert_equal params[:always], "money"
  assert_equal session[:in], "the"
  refute_equal flash[:banana], "stand" # because the flash will have been flushed!

December 7, 2015

Multiple calls to ReactDOM.render can be a super powerful tool. Given a state-ful component Counter

// Initial render into document.body
React.render(<Counter count=0 />, document.body)
// => { state: { count: 0 }, props: { count: 0 } }

// Something internal happens that changes state to 50
// => { state: { count: 50 }, props: { count: 0 } }

// Re-render without unmounting into document.body
React.render(<Counter count=100 />, document.body)
// => { state: { count: 50 }, props: { count: 100 } }

In many use-cases, flux is introduced to distinguish between props and state. If props are changing on the server, this is a nice light-weight way re-render everything, while maintaining some client-side state. (Super helpful in rails in my usage)

November 27, 2015

While playing with webpack in a Rails environment, there are still some variables I want to expose to the window. I came up with this 2-liner to treat exports from the top most bundle as global variables!

export { Whatever, You, Want }
Object.assign(window, exports)

November 14, 2015

When using elm make, the output is determined by the extension.

elm make Main.elm --output main.html # generates html
elm make Main.elm --output main.js # generates js

November 9, 2015

Put it in a Rakefile. Why incur the overhead of ruby my_script, when you can just type rake? It takes a little more time to write, but being able to return to a small folder and type rake -T by convention makes you faster in the long run.

September 29, 2015

You are not allowed to complain about what you are not willing to confront. I saw that in a tweet a while ago, and it is a good word.

Prefixing methods that will change what is on output to the screen with render_ sounds verbose, but it has been helpful as I’ve started to use it more. Another React convention that is informing other areas of development.

August 12, 2015

CORS is real. The part that really tripped me up, is the preflight OPTIONS request.

You can handle this options request in Rails with a nice routing constraint.

match '*', to: 'cors#handle', via: %i(options)

Then set your Access-Control-[Whatever] headers accordingly, and you’re in business.

July 22, 2015

There are a lot of ways that payment can fail. Thankfully, Stripe provides ways to trigger almost every conceivable failure. And they put the credit card values that will trigger these failures into a handy doc.

It’s important to remember, some of these failures will occur when attempting to get a Stripe token. Others will fail when attempting to use the Stripe token.

July 20, 2015

When using Bugsnag within a Rails app, you must use the before_bugsnag_notify macro within your ApplicationController (or similar) to add custom info. I tried to be clever, using the Bugsnag.before_notify_callbacks manually in an initializer. This didn’t work. My assumption is that Bugsnag.before_notify_callbacks.clear is called somewhere internally in the Railtie.

It pays to read the Bugsnag ruby docs.

June 22, 2015

In Rails’ Mailer Previews, you can append .text to the URL to view the text version by default. Way better than reloading, and having to select text from the dropdown!

June 15, 2015

Rails.application.routes.url_helpers can be used to access your URL helpers from anywhere.

May 20, 2015

In JavaScript, document.activeElement gives you the active element. How did I never know this?

April 21, 2015

<<-SOMETHING.strip_heredoc in Ruby, to strip the heredoc, and align to the current level of indentation. Doc

March 3, 2015

When working in Ruby, JSON.parse(payload, symbolize_names: true) will automaticaly symbolize the names.

February 2, 2015

There is no magic for Rails’ enum in fixtures. If you want to use the string value (which is the entire point of using the enum), you need to ERB it up. Something like

  name: Michael Bluth
  occupation: <%= Person.occupations[:actor] %> # because 'actor' won't do it

November 25, 2014

You can use reorder on an ActiveRecordRelation to replace all existing order methods. It’s super useful when merging scopes that may have imported their own ordering that is no longer applicable.

November 24, 2014

Study the docs. As an example, there are so many methods on Enumerable that you can leverage to eliminate temporary variables. Don’t spend all your time reading the docs, but every once and a while it’s good to review what’s already built in the standard library that you don’t need to re-invent.

If you’re looking up a record by anything other than the primary_key, don’t accept arbitrary arguments. Lazily looking up a record is great, but if you’re using something like

def destroy_do_dad(expecting_an_id_but_an_object_was_passed_in)
  DoDad.where(foreign_system_id: expecting_an_id_but_an_object_was_passed_in).destroy

you have a huge vulnerability. #to_param, will come into play, and you’re now potentially finding a completely arbitrary record and destroying it.

November 21, 2014

Let the database do all of the heavy lifting for counting your ActiveRecord objects.

Record.pluck(:owner_id).each_with_object( { |id, counts|
  counts[id] += 1

Sums up the number of records for a owner in Ruby. The same can be achieved via ActiveRecord.

November 10, 2014

When accessing the Rails flash messages, use strings instead of symbols. I thought it was a HashWithIndifferentAccess...but it doesn’t appear to be.

November 8, 2014

Responding to http in Go on Dreamhost is pretty easy. The trick is to use FactCGI to serve it up.

I did this via a trivial conditional for my setup of developing on OSX, and deploying to Linux.

if runtime.GOOS == "linux" {
  fcgi.Serve(nil, nil)
} else {
  http.ListenAndServe(":2112", nil)

To cross-compile to Linux, you use the Go runtime flags.

GOOS=linux GOARCH=386 go build

November 7, 2014

I was reminded how evil DST is. It’s just the worst. Writing tests around it is the best. Just a reminder that 2am-3am on March 8, 2015 DOES NOT EXIST.

November 6, 2014

Some random commands from tinkering with Vagrant today:

  • dscacheutil -flushcache # Flush the DNS cache

JavaScript Array’s map function takes a optional second argument, of what to bind to this.

November 5, 2014

Gulpfiles. I don’t know what I learned about them, but I helped a friend troubleshoot why and gulp-sass combined to produce a Segmentation Fault 11. Something with libsass, and rolling back the node-sass version fixed it.


November 4, 2014

Gourmet Service Objects is a post worth returning to from time to time. After slogging through some code to understand what it did, I wrote it into a service. The code wasn’t substantially different, but the fact that it had a name as first-class citizen instantly made it easier to understand.

Because my dudepal @jabronus gave me an SVG of my avatar, I started learning how to use SVG in the browser. I even made my avatar blink using CSS animations. Supes cool.

November 3, 2014

git log --pretty=oneline gives you the one-line per a commit output.

git log --pretty=format:"%an" gives you formatting on commits. All the interpolations available are listed in the man git-log under “PRETTY FORMATS”.

attr_readonly exists in Rails for making fields immutable. But we’re in Rails, so we don’t use big words like immutable, we use readonly. Caveat: you can still change the values in memory, which has other consequences around validations and any derived values.

October 29, 2014

Having opinions is more fun that trying to please everyone. Engage in helpful debate with reasonable people. Change your mind when presented with new data that should change your mind. Attack the problems together. Defend your teammates, not your opinions.

October 23, 2014

You can be incredibly productive, but feel unproductive. Fixing lots of small bugs leads to this. Keeping a list of everything completed such as Trello helps you remember that you’re making a lot of small progress when it feels like you’re not making any large progress.

There are many ways to write even the simplest statement.

# Whitelisted arguments.  # Which is most readable while being concise?

# 1
trusted = %w[approve reject].find { |i| i == untrusted }

# 2
trusted = (%w[approve reject] & [untrusted]).first

# 3
trusted = %w[approve reject].include?(untrusted) ? untrusted : nil

# 4
trusted = case untrusted; when *%w[approve reject]; untrusted; end

October 22, 2014

Aggressively eliminate state. After working with ReactJS for a bit, I am starting to see the merits of eliminating state. I’m even beginning to like methods prefixed with get and set. Eliminating state means eliminating side-effects.

Writing adolescent JS code seems to lead to better JS code. What I mean by adolescent code, is that it refuses to take responsibility. It lets somebody else own the state of the world. All it does is ask for values, and do something with them.

If you want to launch Vim from a Ruby script, use system 'vim'. Backticks won’t work, because they want to consume STDOUT. exec takes over the process, so you couldn’t do work afterwords. system works.

October 21, 2014

Take breaks.

Lately, I’ve been taking breaks. Today I didn’t. And at end-of-day, the difference in energy level left for friends & family is substantially depleted.

October 20, 2014

Small changes are easier than big changes. Renaming things seems like a huge win, but when you’re renaming big things, small subtleties will emerge. These pitfalls are easier to see in others’ proposed changes than your own.

If you’re going to rename something, have a good purpose for it.

Look for the dumb solution. Sometimes refactoring isn’t needed yet. You don’t know enough about the problem to find the better solution, yet.

October 16, 2014

It’s important to know how to revert a commit, because sometimes you accidentally commit strait to master.

If you caught yourself before pushing upstream, you’re good. Just

git checkout -b temporary
git branch -D master
git checkout master

This assuming it automatically pulls master back down from upstream, which is my default setup.

If you did push upstream, you’ll basically want to create a commit that reverts the latest commit. Hopefully it’s only one commit.

git format-patch -1 HEAD
git apply [newly_created_patch_name] -R

October 15, 2014

You have to mull through a lot of terrible names, and iterate on terrible code to arrive at a consistent, reasonable API. Today I was building an ActiveSupport::Concern whose purpose will be to cache attributes that are expensive to compute. The names of the methods changed a handful of times. And even now they may not be finalized.

I left the code for a few hours, and returned to it with a fresh set of eyes. The names were terrible. Their implied meaning was confusing. But because of this gap, I was able to see some of of the consistent shortcomings. I also saw patterns emerging, that lead to a more consistent API for the final iteration (of the day).

October 14, 2014

I started making a before_filter that would redirect a request from a bot. After returning to the code, I decided it would be better to rescue_from SomeCustomError, with: :what_was_previously_a_before_filter so that the code did not have to run on every single request. This probably amounts to minimal performance gains in terms of actual execution time, but I think it brought clarity to the code by having the happy path occur first.

Taking the time to organize your folders/files into something predictable needs to be done quickly when you’re working with branches of code. Every divergent branch means a delay in making it happen.

October 13, 2014

Reminded of a proposal I made long ago. For responsive design, start at one size, and head in one direction, using either min-width or max-width, but not both.

I spent time today moving some behavior of a model into a concern, specific to that model. Rather than putting it into app/models/concerns/person_pending_request_count I put it into app/models/person/pending_request_count. I liked this change, because it communicated that only Person should be using this. It’s not a general mixin, though it could easily become one. Then in the person class, I just included it with include Person::PendingRequestCount.

September 30, 2014

Rails UJS’ ajax:success and ajax:error only apply to XHRs originating from a data-remote="true" source. If you’d like them to apply to all XHRs in your page or application, you’re gonna have to wire that up.

In slim, you can use <, > or both after your tag to add leading or trailing whitespace, respectively.