Thoughts on Engineering, Photography, and Design.

Hey, I'm Ryan Heath. I design & develop things for a living and play with cameras for fun. This is where I share my thoughts on all of that — and probably more — along the way.

The Proactive Engineer

I’ve been a young engineer, mentored young engineers, and now I manage (some) young engineers. One of the best perspectives a young engineer—or any engineer—can have is being proactive.

Engineering is complicated. There are often multiple teams and departments coinciding with ever-changing requirements. This can provide engineers with a tempting out (or “pause button”) when working on a problem because they feel blocked on some level. Does something like this sound familiar?

We can’t work on that yet because there’s no API.

Quite often, though, there’s more an engineer can do than claiming blockers. With minimal additional effort, let’s see how much more helpful a response like this might be:

We can’t work on that yet because there’s no API. But I spent some time thinking about what inputs and outputs we would need to properly build X feature, and wrote up my notes as a proposal for the backend team’s consideration.

Makes a difference, right?

It’s easy to throw things over the fence. It takes intentional effort to avoid it. But when you do, that proactive mindset can go a long way within a team and helps nurture a problem solving culture. It’s not about you, me, or them. It’s about solving a problem and helping everyone involved come up with the best outcome for the situation.

We all want to work with helpful, caring individuals… a proactive brain can help convey that to others.

How to continue making kerosene lamps on the eve of electricity

I don’t think I fully believed in AI building software until fooling around with ChatGPT. Maybe it won’t affect software development like it feels like it might, but I don’t think it can be ignored any longer.

I like to imagine that all of us in software development, as it looks today, are busy making beautiful kerosene lamps in all shapes and sizes. We’re improving the burn efficiency. We’re finding ever clearer forms of glass to let the light through. We’re tinkering with a formula that’s been around for a long time. But as we do, Edison and Tesla are busy inventing electricity in the other room.

Setting Ownership in Rails

There’s a common pattern in a lot of applications to track who did what. Who created this post? Who was the last person to update it? Maybe it’s for accountability, maybe it’s because your client is nosy.

There are gems for this, but it’s such a simple thing, that extra dependency isn’t really worth it. So let’s take a look at a pretty simple way to achieve this in Rails 7 using a concern:

 1module Ownership
 2  extend ActiveSupport::Concern
 4  included do
 5    before_validation :set_ownership
 7    scope :created_by, ->(user_id) {
 8      where(creator_id: user_id)
 9    }
10    scope :updated_by, ->(user_id) {
11      where(updater_id: user_id)
12    }
14    belongs_to :creator, class_name: 'User',
15      foreign_key: 'creator_id', optional: true
16    belongs_to :updater, class_name: 'User',
17      foreign_key: 'updater_id'
19    validates :creator_id, :updater_id,
20      presence: true
21  end
23  private
25  def set_ownership
26    current_user = Current.user
28    if new_record?
29      self.creator_id =
30      self.updater_id =
31    else
32      self.updater_id =
33    end
34  end

Now, for any model that has creator_id and updater_id columns, you just have to include the Ownership module:

 1class Post < ApplicationRecord
 2  include Ownership
 4  # ...
 7>> @post = Post.find(1)
 8>> @post.creator
 9# => #<User id: 10 ... >
10>> @post.updator
11# => #<User id: 20 ... >

And whenever a Post is created, the creator is automagically set; similarly, whenever any Post is updated, the updater is automagically set. This, of course, assumes your application has user sessions, since you obviously need to know who’s logged in doing the creating and updating.