novice designers are best served by writing test-first code. Their lack of design skills may make this bafflingly difficult but if they persevere they will at least have testable code — Sandi Metz in POODR
I think I’m just starting to get past the bafflingly difficult stage!
Reason # 1,562 that I love Ruby (and the frameworks it has fostered):
ActiveSupport::Duration has plurals of duration methods so 1.hour
and 2.hours
both work.
Enjoyed hearing the emphasis on simplicity and speed of deployment on the latest Ruby Rogues episode.
I love using Heroku to speed up deployment and feedback but I’m also keen to learn more about where Dokku and Beanstalk (different to the AWS product!!!) might fit in.
I run up a new Rails app often enough that I have a certain way I like to do things, but infrequently enough that I normally have to spend a bit of time on Google/Stack Overflow remembering how to do it that way. This checklist is my attempt to remedy that.
If I’m starting a new project I want to be starting with the latest (usually stable) ruby.
brew upgrade rbenv ruby-build
rbenv install -l
rbenv install 2.5.3
rbenv global 2.5.3
I also want it to be on the latest (again, stable) Rails.
gem list rails --remote -e --all
(-e for exact match, –all shows all versions, not just the latest… is optional)
gem install rails -v 5.2.1
gem install rails
to get latestgem install rails -v '~> 5.0
to get latest 5.x.y versionMy philosophy (as a relative newbie) is to pretty much use Rails “The Rails Way” (the Basecamp way?). At this stage that means I don’t monkey with the default gems (with one exception), I just use the default test framework, javascript framework, etc initially. I do change my dev database to Postgres however.
rails new --skip-bundle --database=postgresql <app-name>
bundle
rails haml:erb2haml
I use Github mainly due to inertia/convenience. I have tried Bitbucket, and like being able to hide my work in private repositories for free, but it’s probably good for me to develop “in the open” a bit more.
git add .
git commit
:
git remote add origin git@github.com:<user>/<repo-name>.git
git push -u origin master
Next steps should probably be along the lines of (not necessarily in this order):
These are some things I might want to think about enhancing next time I use this checklist (or review this process).
curl -H "Authorization: token 12d3fd45f6ac7c89012345678db901ac2a3456f7" '[api.github.com/user/repo...](https://api.github.com/user/repos') -d '{"name":"test-repo"}'
Most people know the basic keyboard shortcuts ⌘X
, ⌘C
and ⌘V
for cut, copy and paste but, if you like to keep your hands on the keyboard as much as possible, an important related Mac keyboard shortcut to know is ⌘⌥⇧V
(command-option-shift-v) for “Paste and Match Style” (or “Paste as Text” which is how I think of it).
Under the hood, Paste and Match Style simply pastes in the text only version of whatever is on your clipboard, thereby stripping out fonts, colours, sizes and other rich text formatting.
This can be useful when pasting styled text into Pages or Mail (for example), when you just want the raw text, not all the styles.
Another time it comes in handy is when copying and pasting links. If you right click on the Micro.blog “Timeline” link above and choose “Copy Link” you’ll get a rich text link on your clipboard. If you try and paste it into the body of an email message you’ll get the word “Timeline” linked to the url. If you just want the URL you can use ⌘⌥⇧V
to “Paste and Match Style”, pasting just the unformatted URL.
Notes
⌘⇧V
(no option key)Nearly finished the Upcase Intermediate Rails course. Last lesson is on search and in addition to mentioning Elasticsearch (which I’ve heard of but not yet used) they discussed Solr (via Sunspot) which is completely new to me.
Much to learn!
I’m going through the (now free 🎉) Upcase course by Thoughtbot. In lesson 3 I just learned about rails db:migrate:redo
to test rollback and migration in one go.
(On that particular exercise I still chose to run them separately so I could examine the DB in between though)
Listening to episode 10 of the Ruby Testing Podcast and Zach mentioned Page Object Model, a way to make integration tests more robust against minor interface changes.
Keen to investigate it more.
Update: A more Ruby focused link
In a REST API I was writing, I wanted certain unlikely failures effecting customers to get logged to BugSnag as warnings so we would know if there was a pattern of failures, even if customers didn’t follow the instructions on the page to let us know.
From what I could tell reading the docs, BugSnag wanted me to pass it an error (exception) of some kind but these failures weren’t raising exceptions, they were just returning appropriate 4xx HTTP error codes.
There’s probably a better way of doing it but my eventual solution involved creating, but not raising, an error:
e = StandardError.new(‘Verified successfully but couldn’t fetch any records’)
Bugsnag.notify(e)
By the way, I would normally use a more descriptive variable name but I think this is one of those rare exceptions (pun not intended) where the meaning is so obvious and the variable is so short lived that it’s acceptable. A bit like using i
and j
as variables in a loop.
I tested this code from the production console to make sure it worked and that notifications came through to our internal chat app. What I noticed is that, perhaps because I didn’t raise
the errors, the Bugsnags didn’t include helpful backtrace information like file names, line numbers or method names. The docs revealed a set_backtrace
method and StackOverflow pointed me in the direction of [caller](https://ruby-doc.org/core-2.5.3/Kernel.html)
.
Of course I found myself using this same code 4 times in the same file, an obvious candidate to split into a method. Of those 4 times, they were split evenly between warnings and errors so the method needed to allow for that. I also wanted to be able to add a tab to Bugsnag with arbitrary information. Skipping to the finished product, the end result was:
def notify_via_bugsnag(message:, severity: 'warning', aditional_info: {})
e = RuntimeError.new message
e.set_backtrace caller(2)
Bugsnag.notify(e) do |report|
report.severity = severity
report.add_tab(:appname_API, additional_info) if additional_info.present?
end
end
The main thing to note is the addition of (2)
to caller
. Because I’m setting the backtrace from within a called method I want it to start one frame higher in the stack.
I then consumed this method in the controller with code like this:
notify_via_bugsnag(message: 'Requestor was verified but student data wasn\'t saved',
severity: 'error',
additional_info: {
student_id: params[:id],
})
head :unprocessable_entity
📚 I’m reading Seeing What Others Don’t by Gary Klein and came across this great quote:
The greatest obstacle to knowledge is not ignorance; it is the illusion of knowledge. — Daniel Boorstin
While I’m on the book theme, we listened to “Here Be Monsters” by Alan Snow (read by Bill Wallis) in the car as a family.
I’m a huge fan of borrowing audio books and ebooks from our local library on my phone using Bolinda BorrowBox. So convenient! 📚
These holidays I also re-read “Only Time Will Tell” by Jeffrey Archer (2013). It was a great read and I’m looking forward to reading the rest of the series (currently on reserve). 📚