mirror of
https://github.com/jbranchaud/til
synced 2026-01-20 15:38:02 +00:00
Compare commits
17 Commits
79ae007109
...
1eacabb90f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1eacabb90f | ||
|
|
fc93ecfed4 | ||
|
|
a07a19e6d9 | ||
|
|
951a2f04ad | ||
|
|
6b9ec224b8 | ||
|
|
c33be14ec2 | ||
|
|
2922bbdd6a | ||
|
|
2e72ec1160 | ||
|
|
baab5738e7 | ||
|
|
191c9d6d9d | ||
|
|
25b5677260 | ||
|
|
df3492d4ef | ||
|
|
bd49b31bb0 | ||
|
|
4ff1a381d1 | ||
|
|
0bfeb0e236 | ||
|
|
69917e4c93 | ||
|
|
c79e4c45bf |
16
README.md
16
README.md
@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
|
|||||||
|
|
||||||
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
||||||
|
|
||||||
_1434 TILs and counting..._
|
_1448 TILs and counting..._
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -376,6 +376,7 @@ _1434 TILs and counting..._
|
|||||||
|
|
||||||
- [Access Go Docs Offline](go/access-go-docs-offline.md)
|
- [Access Go Docs Offline](go/access-go-docs-offline.md)
|
||||||
- [Build For A Specific OS And Architecture](go/build-for-a-specific-os-and-architecture.md)
|
- [Build For A Specific OS And Architecture](go/build-for-a-specific-os-and-architecture.md)
|
||||||
|
- [Find Executables Installed By Go](go/find-executables-installed-by-go.md)
|
||||||
- [Not So Random](go/not-so-random.md)
|
- [Not So Random](go/not-so-random.md)
|
||||||
- [Replace The Current Process With An External Command](go/replace-the-current-process-with-an-external-command.md)
|
- [Replace The Current Process With An External Command](go/replace-the-current-process-with-an-external-command.md)
|
||||||
- [Sleep For A Duration](go/sleep-for-a-duration.md)
|
- [Sleep For A Duration](go/sleep-for-a-duration.md)
|
||||||
@@ -390,8 +391,10 @@ _1434 TILs and counting..._
|
|||||||
|
|
||||||
### Heroku
|
### Heroku
|
||||||
|
|
||||||
|
- [Connect To A Database By Color](heroku/connect-to-a-database-by-color.md)
|
||||||
- [Deploy A Review App To A Different Stack](heroku/deploy-a-review-app-to-a-different-stack.md)
|
- [Deploy A Review App To A Different Stack](heroku/deploy-a-review-app-to-a-different-stack.md)
|
||||||
- [Diagnose Problems In A Heroku Postgres Database](heroku/diagnose-problems-in-a-heroku-postgres-database.md)
|
- [Diagnose Problems In A Heroku Postgres Database](heroku/diagnose-problems-in-a-heroku-postgres-database.md)
|
||||||
|
- [Open Dashboard For Specific Add-On](heroku/open-dashboard-for-specific-add-on.md)
|
||||||
- [Run SQL Against Remote Postgres Database](heroku/run-sql-against-remote-postgres-database.md)
|
- [Run SQL Against Remote Postgres Database](heroku/run-sql-against-remote-postgres-database.md)
|
||||||
- [Set And Show Heroku Env Variables](heroku/set-and-show-heroku-env-variables.md)
|
- [Set And Show Heroku Env Variables](heroku/set-and-show-heroku-env-variables.md)
|
||||||
- [SSH Into Heroku Server Hosting App](heroku/ssh-into-heroku-server-hosting-app.md)
|
- [SSH Into Heroku Server Hosting App](heroku/ssh-into-heroku-server-hosting-app.md)
|
||||||
@@ -570,6 +573,7 @@ _1434 TILs and counting..._
|
|||||||
- [Access All Screen And Video Capture Options](mac/access-all-screen-and-video-capture-options.md)
|
- [Access All Screen And Video Capture Options](mac/access-all-screen-and-video-capture-options.md)
|
||||||
- [Access System Information On OS X](mac/access-system-information-on-osx.md)
|
- [Access System Information On OS X](mac/access-system-information-on-osx.md)
|
||||||
- [Access Unsupported Screen Resolutions With RDM](mac/access-unsupported-screen-resolutions-with-rdm.md)
|
- [Access Unsupported Screen Resolutions With RDM](mac/access-unsupported-screen-resolutions-with-rdm.md)
|
||||||
|
- [Check Network Quality Stats From The Command Line](mac/check-network-quality-stats-from-the-command-line.md)
|
||||||
- [Clean Up Old Homebrew Files](mac/clean-up-old-homebrew-files.md)
|
- [Clean Up Old Homebrew Files](mac/clean-up-old-homebrew-files.md)
|
||||||
- [Convert An HEIC Image File To JPG](mac/convert-an-heic-image-file-to-jpg.md)
|
- [Convert An HEIC Image File To JPG](mac/convert-an-heic-image-file-to-jpg.md)
|
||||||
- [Default Screenshot Location](mac/default-screenshot-location.md)
|
- [Default Screenshot Location](mac/default-screenshot-location.md)
|
||||||
@@ -634,6 +638,7 @@ _1434 TILs and counting..._
|
|||||||
|
|
||||||
### Next.js
|
### Next.js
|
||||||
|
|
||||||
|
- [Avoid Conflicting Files](nextjs/avoid-conflicting-files.md)
|
||||||
- [Create Files And Directories For Dynamic Routes](nextjs/create-files-and-directories-for-dynamic-routes.md)
|
- [Create Files And Directories For Dynamic Routes](nextjs/create-files-and-directories-for-dynamic-routes.md)
|
||||||
- [Define URL Redirects In The Next Config](nextjs/define-url-redirects-in-the-next-config.md)
|
- [Define URL Redirects In The Next Config](nextjs/define-url-redirects-in-the-next-config.md)
|
||||||
- [Fetch Does Not Work In API Serverless Function](nextjs/fetch-does-not-work-in-api-serverless-function.md)
|
- [Fetch Does Not Work In API Serverless Function](nextjs/fetch-does-not-work-in-api-serverless-function.md)
|
||||||
@@ -731,6 +736,7 @@ _1434 TILs and counting..._
|
|||||||
- [Fizzbuzz With Common Table Expressions](postgres/fizzbuzz-with-common-table-expressions.md)
|
- [Fizzbuzz With Common Table Expressions](postgres/fizzbuzz-with-common-table-expressions.md)
|
||||||
- [Force SSL When Making A psql Connection](postgres/force-ssl-when-making-a-psql-connection.md)
|
- [Force SSL When Making A psql Connection](postgres/force-ssl-when-making-a-psql-connection.md)
|
||||||
- [Generate A UUID](postgres/generate-a-uuid.md)
|
- [Generate A UUID](postgres/generate-a-uuid.md)
|
||||||
|
- [Generate Modern Primary Key Columns](postgres/generate-modern-primary-key-columns.md)
|
||||||
- [Generate Random UUIDs Without An Extension](postgres/generate-random-uuids-without-an-extension.md)
|
- [Generate Random UUIDs Without An Extension](postgres/generate-random-uuids-without-an-extension.md)
|
||||||
- [Generate Series Of Numbers](postgres/generate-series-of-numbers.md)
|
- [Generate Series Of Numbers](postgres/generate-series-of-numbers.md)
|
||||||
- [Generating UUIDs With pgcrypto](postgres/generating-uuids-with-pgcrypto.md)
|
- [Generating UUIDs With pgcrypto](postgres/generating-uuids-with-pgcrypto.md)
|
||||||
@@ -895,6 +901,8 @@ _1434 TILs and counting..._
|
|||||||
- [Find Or Create A Record With FactoryBot](rails/find-or-create-a-record-with-factory-bot.md)
|
- [Find Or Create A Record With FactoryBot](rails/find-or-create-a-record-with-factory-bot.md)
|
||||||
- [Find Records With Multiple Associated Records](rails/find-records-with-multiple-associated-records.md)
|
- [Find Records With Multiple Associated Records](rails/find-records-with-multiple-associated-records.md)
|
||||||
- [Force All Users To Sign Out](rails/force-all-users-to-sign-out.md)
|
- [Force All Users To Sign Out](rails/force-all-users-to-sign-out.md)
|
||||||
|
- [Generate A Model](rails/generate-a-model.md)
|
||||||
|
- [Generate A Rails App From The Main Branch](rails/generate-a-rails-app-from-the-main-branch.md)
|
||||||
- [Generating And Executing SQL](rails/generating-and-executing-sql.md)
|
- [Generating And Executing SQL](rails/generating-and-executing-sql.md)
|
||||||
- [Get A Quick Approximate Count Of A Large Table](rails/get-a-quick-approximate-count-of-a-large-table.md)
|
- [Get A Quick Approximate Count Of A Large Table](rails/get-a-quick-approximate-count-of-a-large-table.md)
|
||||||
- [Get ActiveRecord Attribute Directly From Database](rails/get-active-record-attribute-directly-from-database.md)
|
- [Get ActiveRecord Attribute Directly From Database](rails/get-active-record-attribute-directly-from-database.md)
|
||||||
@@ -978,6 +986,7 @@ _1434 TILs and counting..._
|
|||||||
- [Update Column Versus Update Attribute](rails/update-column-versus-update-attribute.md)
|
- [Update Column Versus Update Attribute](rails/update-column-versus-update-attribute.md)
|
||||||
- [Upgrading Your Manifest For Sprocket's 4](rails/upgrading-your-manifest-for-sprockets-4.md)
|
- [Upgrading Your Manifest For Sprocket's 4](rails/upgrading-your-manifest-for-sprockets-4.md)
|
||||||
- [Use IRB And Ruby Flags With Rails Console](rails/use-irb-and-ruby-flags-with-rails-console.md)
|
- [Use IRB And Ruby Flags With Rails Console](rails/use-irb-and-ruby-flags-with-rails-console.md)
|
||||||
|
- [Validate Column Data With Check Constraints](rails/validate-column-data-with-check-constraints.md)
|
||||||
- [Verify And Read A Signed Cookie Value](rails/verify-and-read-a-signed-cookie-value.md)
|
- [Verify And Read A Signed Cookie Value](rails/verify-and-read-a-signed-cookie-value.md)
|
||||||
- [Where Am I In The Partial Iteration?](rails/where-am-i-in-the-partial-iteration.md)
|
- [Where Am I In The Partial Iteration?](rails/where-am-i-in-the-partial-iteration.md)
|
||||||
- [Why Redirect And Return In Controllers](rails/why-redirect-and-return-in-controllers.md)
|
- [Why Redirect And Return In Controllers](rails/why-redirect-and-return-in-controllers.md)
|
||||||
@@ -1098,7 +1107,9 @@ _1434 TILs and counting..._
|
|||||||
|
|
||||||
### RSpec
|
### RSpec
|
||||||
|
|
||||||
|
- [Avoid Accidentally Disabling Pry](rspec/avoid-accidentally-disabling-pry.md)
|
||||||
- [Check Specific Arguments To Received Method](rspec/check-specific-arguments-to-received-method.md)
|
- [Check Specific Arguments To Received Method](rspec/check-specific-arguments-to-received-method.md)
|
||||||
|
- [Configure Tests To Run In Random Order](rspec/configure-tests-to-run-in-random-order.md)
|
||||||
- [Find Minimal Set Of Tests Causing A Flicker](rspec/find-minimal-set-of-tests-causing-a-flicker.md)
|
- [Find Minimal Set Of Tests Causing A Flicker](rspec/find-minimal-set-of-tests-causing-a-flicker.md)
|
||||||
- [Format Test Results As A JSON File](rspec/format-test-results-as-a-json-file.md)
|
- [Format Test Results As A JSON File](rspec/format-test-results-as-a-json-file.md)
|
||||||
- [Run Tests With Documentation Formatting](rspec/run-tests-with-documentation-formatting.md)
|
- [Run Tests With Documentation Formatting](rspec/run-tests-with-documentation-formatting.md)
|
||||||
@@ -1178,6 +1189,7 @@ _1434 TILs and counting..._
|
|||||||
- [Map With Index Over An Array](ruby/map-with-index-over-an-array.md)
|
- [Map With Index Over An Array](ruby/map-with-index-over-an-array.md)
|
||||||
- [Mock Method Chain Calls With RSpec](ruby/mock-method-chain-calls-with-rspec.md)
|
- [Mock Method Chain Calls With RSpec](ruby/mock-method-chain-calls-with-rspec.md)
|
||||||
- [Mocking Requests With Partial URIs Using Regex](ruby/mocking-requests-with-partial-uris-using-regex.md)
|
- [Mocking Requests With Partial URIs Using Regex](ruby/mocking-requests-with-partial-uris-using-regex.md)
|
||||||
|
- [Multi-Line Comments](ruby/multi-line-comments.md)
|
||||||
- [Named Regex Captures Are Assigned To Variables](ruby/named-regex-captures-are-assigned-to-variables.md)
|
- [Named Regex Captures Are Assigned To Variables](ruby/named-regex-captures-are-assigned-to-variables.md)
|
||||||
- [Navigate Back In The Browser With Capybara](ruby/navigate-back-in-the-browser-with-capybara.md)
|
- [Navigate Back In The Browser With Capybara](ruby/navigate-back-in-the-browser-with-capybara.md)
|
||||||
- [Next And Previous Floats](ruby/next-and-previous-floats.md)
|
- [Next And Previous Floats](ruby/next-and-previous-floats.md)
|
||||||
@@ -1216,6 +1228,7 @@ _1434 TILs and counting..._
|
|||||||
- [Silence The Output Of A Ruby Statement In Pry](ruby/silence-the-output-of-a-ruby-statement-in-pry.md)
|
- [Silence The Output Of A Ruby Statement In Pry](ruby/silence-the-output-of-a-ruby-statement-in-pry.md)
|
||||||
- [Single And Double Quoted String Notation](ruby/single-and-double-quoted-string-notation.md)
|
- [Single And Double Quoted String Notation](ruby/single-and-double-quoted-string-notation.md)
|
||||||
- [Skip Specific CVEs When Auditing Your Bundle](ruby/skip-specific-cves-when-auditing-your-bundle.md)
|
- [Skip Specific CVEs When Auditing Your Bundle](ruby/skip-specific-cves-when-auditing-your-bundle.md)
|
||||||
|
- [Skip The Front Of An Array With Drop](ruby/skip-the-front-of-an-array-with-drop.md)
|
||||||
- [Specify Dependencies For A Rake Task](ruby/specify-dependencies-for-a-rake-task.md)
|
- [Specify Dependencies For A Rake Task](ruby/specify-dependencies-for-a-rake-task.md)
|
||||||
- [Specify How Random Array#sample Is](ruby/specify-how-random-array-sample-is.md)
|
- [Specify How Random Array#sample Is](ruby/specify-how-random-array-sample-is.md)
|
||||||
- [Split A Float Into Its Integer And Decimal](ruby/split-a-float-into-its-integer-and-decimal.md)
|
- [Split A Float Into Its Integer And Decimal](ruby/split-a-float-into-its-integer-and-decimal.md)
|
||||||
@@ -1350,6 +1363,7 @@ _1434 TILs and counting..._
|
|||||||
- [Command Line Length Limitations](unix/command-line-length-limitations.md)
|
- [Command Line Length Limitations](unix/command-line-length-limitations.md)
|
||||||
- [Compare Two Variables In A Bash Script](unix/compare-two-variables-in-a-bash-script.md)
|
- [Compare Two Variables In A Bash Script](unix/compare-two-variables-in-a-bash-script.md)
|
||||||
- [Configure cd To Behave Like pushd In Zsh](unix/configure-cd-to-behave-like-pushd-in-zsh.md)
|
- [Configure cd To Behave Like pushd In Zsh](unix/configure-cd-to-behave-like-pushd-in-zsh.md)
|
||||||
|
- [Convert SVG To Favicon](unix/convert-svg-to-favicon.md)
|
||||||
- [Copying File Contents To System Paste Buffer](unix/copying-file-contents-to-system-paste-buffer.md)
|
- [Copying File Contents To System Paste Buffer](unix/copying-file-contents-to-system-paste-buffer.md)
|
||||||
- [Copying Nested Directories With Ditto](unix/copying-nested-directories-with-ditto.md)
|
- [Copying Nested Directories With Ditto](unix/copying-nested-directories-with-ditto.md)
|
||||||
- [Count The Lines In A CSV Where A Column Is Empty](unix/count-the-lines-in-a-csv-where-a-column-is-empty.md)
|
- [Count The Lines In A CSV Where A Column Is Empty](unix/count-the-lines-in-a-csv-where-a-column-is-empty.md)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Sometimes when viewing a page, you realize you want to keep that page open
|
|||||||
but also go back to the previous page to view something else. An easy way of
|
but also go back to the previous page to view something else. An easy way of
|
||||||
achieving this is to duplicate the current tab and then go back.
|
achieving this is to duplicate the current tab and then go back.
|
||||||
|
|
||||||
To duplicate the current tab hit `Cmd+Enter` while the focus is on the URL
|
To duplicate the current tab, hit `Cmd+Enter` (macOS) or `Alt+Enter` (Windows) while the focus is on the URL
|
||||||
bar.
|
bar.
|
||||||
|
|
||||||
If the URL bar is not in focus, then first hit `Cmd+L` to focus followed by
|
If the URL bar is not in focus, then first hit `Cmd+L` to focus followed by
|
||||||
|
|||||||
26
go/find-executables-installed-by-go.md
Normal file
26
go/find-executables-installed-by-go.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Find Executables Installed By Go
|
||||||
|
|
||||||
|
When you install an executable using `go install`, it puts that executable in
|
||||||
|
the `bin` directory designated by the `GOBIN` environment variable. If that env
|
||||||
|
var isn't set, then it falls back to one of `$GOPATH/bin` or `$HOME/go/bin`.
|
||||||
|
|
||||||
|
When I run `go help install`, it tells me as much:
|
||||||
|
|
||||||
|
```
|
||||||
|
Executables are installed in the directory named by the GOBIN environment
|
||||||
|
variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH
|
||||||
|
environment variable is not set.
|
||||||
|
```
|
||||||
|
|
||||||
|
So, if I am to install something like [`tern`](https://github.com/jackc/tern),
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ go install github.com/jackc/tern/v2@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
it is going to place that binary in `~/go/bin` for me.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ which tern
|
||||||
|
/Users/jbranchaud/go/bin/tern
|
||||||
|
```
|
||||||
29
heroku/connect-to-a-database-by-color.md
Normal file
29
heroku/connect-to-a-database-by-color.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Connect To A Database By Color
|
||||||
|
|
||||||
|
All of your PostgreSQL databases in Heroku are given attachment names that use
|
||||||
|
a random color. This might be _pink_, _brown_, _cobalt_, etc. And the
|
||||||
|
attachment names then look like `HEROKU_POSTGRESQL_PINK`,
|
||||||
|
`HEROKU_POSTGRESQL_BROWN`, `HEROKU_POSTGRESQL_COBALT`, etc.
|
||||||
|
|
||||||
|
We can connect to a Heroku-managed PostgreSQL instance from the command-line
|
||||||
|
like so:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ heroku pg:psql --app my-app
|
||||||
|
```
|
||||||
|
|
||||||
|
This is going to connect to the _default_ database which is the one with the
|
||||||
|
`DATABASE_URL` attachment.
|
||||||
|
|
||||||
|
There are lots of instances where we may have other databases besides the
|
||||||
|
primary (e.g. let's say we have a read replica follower). If we want to connect
|
||||||
|
to that one, we can do so by _color_.
|
||||||
|
|
||||||
|
If that database's attachment is `HEROKU_POSTGRESQL_IVORY`, then we'd connect
|
||||||
|
to it like so:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ heroku pg:psql ivory --app my-app
|
||||||
|
```
|
||||||
|
|
||||||
|
[source](https://devcenter.heroku.com/articles/managing-heroku-postgres-using-cli#pg-psql)
|
||||||
17
heroku/open-dashboard-for-specific-add-on.md
Normal file
17
heroku/open-dashboard-for-specific-add-on.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Open Dashboard For Specific Add-On
|
||||||
|
|
||||||
|
The number of times I've needed to check the papertrail logs for my
|
||||||
|
Heroku-hosted Rails app is a lot. I open a browser tab, go through several
|
||||||
|
layers of navigation to get to my app's dashboard, and then click the
|
||||||
|
papertrail link under _Add-ons_.
|
||||||
|
|
||||||
|
There is a much quicker way using the Heroku CLI.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ heroku addons:open papertrail -a my-app-name
|
||||||
|
Opening https://addons-sso.heroku.com/apps/abc123/addons/efg456...
|
||||||
|
```
|
||||||
|
|
||||||
|
It sends you to an add-ons SSO link in the browser which authenticates you and
|
||||||
|
drops you into the dashboard for that specific add-on. You just need to specify
|
||||||
|
the add-on name and the app name.
|
||||||
44
mac/check-network-quality-stats-from-the-command-line.md
Normal file
44
mac/check-network-quality-stats-from-the-command-line.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Check Network Quality Stats From The Command Line
|
||||||
|
|
||||||
|
MacOS comes with a little known CLI utility for checking your current network
|
||||||
|
quality statistics. It is aptly named `networkQuality`.
|
||||||
|
|
||||||
|
Here is what a basic run of the tool might output:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ networkQuality
|
||||||
|
|
||||||
|
...
|
||||||
|
Downlink: capacity 281.430 Mbps, responsiveness 101 RPM - Uplink: capacity 16.629 Mbps, responsiveness 101 R
|
||||||
|
Downlink: capacity 285.534 Mbps, responsiveness 101 RPM - Uplink: capacity 16.028 Mbps, responsiveness 101 R
|
||||||
|
==== SUMMARY ====
|
||||||
|
Uplink capacity: 22.982 Mbps
|
||||||
|
Downlink capacity: 288.152 Mbps
|
||||||
|
Responsiveness: Low (93 RPM)
|
||||||
|
Idle Latency: 26.375 milliseconds
|
||||||
|
```
|
||||||
|
|
||||||
|
You can get an even more detailed summary with the `-v` option:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ networkQuality -v
|
||||||
|
|
||||||
|
...
|
||||||
|
==== SUMMARY ====
|
||||||
|
Uplink capacity: 18.257 Mbps (Accuracy: High)
|
||||||
|
Downlink capacity: 469.355 Mbps (Accuracy: High)
|
||||||
|
Responsiveness: Medium (252 RPM) (Accuracy: High)
|
||||||
|
Idle Latency: 25.583 milliseconds (Accuracy: High)
|
||||||
|
Interface: en0
|
||||||
|
Uplink bytes transferred: 19.750 MB
|
||||||
|
Downlink bytes transferred: 488.265 MB
|
||||||
|
Uplink Flow count: 8
|
||||||
|
Downlink Flow count: 12
|
||||||
|
Start: 9/24/24, 11:06:20 AM
|
||||||
|
End: 9/24/24, 11:06:30 AM
|
||||||
|
OS Version: Version 13.5.2 (Build 22G91)
|
||||||
|
```
|
||||||
|
|
||||||
|
See `man networkQuality` for more details.
|
||||||
|
|
||||||
|
[source](https://cyberhost.uk/the-hidden-macos-speedtest-tool-networkquality/)
|
||||||
36
nextjs/avoid-conflicting-files.md
Normal file
36
nextjs/avoid-conflicting-files.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Avoid Conflicting Files
|
||||||
|
|
||||||
|
When Next.js is bundling and building your project, it will get completely
|
||||||
|
tripped up by any instance of conflicting project files. What I mean by
|
||||||
|
conflicting project files are two JavaScript or TypeScript (or flavors of JSX
|
||||||
|
files) that would resolve to the same thing.
|
||||||
|
|
||||||
|
Here is one example where the extensions differ:
|
||||||
|
|
||||||
|
```
|
||||||
|
src/pages/welcome.tsx
|
||||||
|
src/pages/welcome.jsx
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is another example where the paths differ but the bundled result would
|
||||||
|
conflict:
|
||||||
|
|
||||||
|
```
|
||||||
|
src/pages/welcome.tsx
|
||||||
|
src/pages/welcome/index.tsx
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have any instances of these conflicting files, you'll be presented with
|
||||||
|
a beguiling and cryptic error message when trying to run the dev server.
|
||||||
|
|
||||||
|
```
|
||||||
|
TypeError [ERR_INVALID_ARG_TYPE]: The "to" argument must be of type string. Received undefined
|
||||||
|
at new NodeError (node:internal/errors:405:5)
|
||||||
|
at validateString (node:internal/validators:162:11)
|
||||||
|
at Object.relative (node:path:1191:5)
|
||||||
|
at Watchpack.<anonymous> (/my_app/node_modules/.pnpm/next@14.2.5_@babel+core@7.24.9_react-dom@18.3.1_react@18.3.1/node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.js:381:55) {
|
||||||
|
code: 'ERR_INVALID_ARG_TYPE'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
One of those files needs to go. Remove one of them and you'll be good to go.
|
||||||
43
postgres/generate-modern-primary-key-columns.md
Normal file
43
postgres/generate-modern-primary-key-columns.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Generate Modern Primary Key Columns
|
||||||
|
|
||||||
|
Chances are if you have looked at some examples, blog posts, or real-world
|
||||||
|
instances of a `create table` statement, it defined the primary key with
|
||||||
|
`serial` (or `bigserial`).
|
||||||
|
|
||||||
|
```sql
|
||||||
|
create table books (
|
||||||
|
id serial primary key,
|
||||||
|
title text not null,
|
||||||
|
author text not null,
|
||||||
|
created_at timestamptz not null default now(),
|
||||||
|
updated_at timestamptz not null default now()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `serial` syntax is everywhere, but for quite a while now it has not been
|
||||||
|
the recommended way to define a primary key column for the `int` or `bigint`
|
||||||
|
data types.
|
||||||
|
|
||||||
|
The ["Don't Do This" page of the PostgreSQL
|
||||||
|
wiki](https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_serial) says
|
||||||
|
"Don't use serial".
|
||||||
|
|
||||||
|
> For new applications, identity columns should be used instead. The serial
|
||||||
|
> types have some weird behaviors that make schema, dependency, and permission
|
||||||
|
> management unnecessarily cumbersome.
|
||||||
|
|
||||||
|
The modern way to define a primary key column for `int` or `bigint` is with a
|
||||||
|
generated identity column.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
create table books (
|
||||||
|
id int primary key generated always as identity,
|
||||||
|
title text not null,
|
||||||
|
author text not null,
|
||||||
|
created_at timestamptz not null default now(),
|
||||||
|
updated_at timestamptz not null default now()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Check out the PostgreSQL docs for more about [identity
|
||||||
|
columns](https://www.postgresql.org/docs/17/ddl-identity-columns.html).
|
||||||
26
rails/generate-a-model.md
Normal file
26
rails/generate-a-model.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Generate A Model
|
||||||
|
|
||||||
|
The `rails` CLI comes with a variety of generators. Perhaps the mostly common
|
||||||
|
one to use is the _model_ generator.
|
||||||
|
|
||||||
|
The model generator will create a migration and a model file for the entity
|
||||||
|
that you name. In the following example `Book` will result in a
|
||||||
|
`app/models/book.rb` file as well as a migration file for a `books` table.
|
||||||
|
These generators know the singular and plural conventions.
|
||||||
|
|
||||||
|
At the end of the command is a series of field definitions containing the field
|
||||||
|
_name_ and field _type_. These are used in the migration file for defining
|
||||||
|
columns on the new table.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
❯ bin/rails generate model Book title:string publication_date:date author:string
|
||||||
|
invoke active_record
|
||||||
|
create db/migrate/20240920223447_create_books.rb
|
||||||
|
create app/models/book.rb
|
||||||
|
invoke rspec
|
||||||
|
create spec/models/book_spec.rb
|
||||||
|
```
|
||||||
|
|
||||||
|
You may also notice that an `rspec` action was invoked as part of this
|
||||||
|
generator. That is because I have the `rspec-rails` gem in my project. That gem
|
||||||
|
hooks into the model generator so that a model spec also gets generated. Handy!
|
||||||
27
rails/generate-a-rails-app-from-the-main-branch.md
Normal file
27
rails/generate-a-rails-app-from-the-main-branch.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Generate A Rails App From The Main Branch
|
||||||
|
|
||||||
|
Typically you are going to want to generate a Rails app using some officially
|
||||||
|
released version of the framework. These releases have been thoroughly tested,
|
||||||
|
have received patches, and can guarantee a certain level of stability.
|
||||||
|
|
||||||
|
However, if you are wanting to try out the latest, unreleased features, you may
|
||||||
|
want to generate a fresh Rails app based off the current state of the `main`
|
||||||
|
branch of the `rails` repository.
|
||||||
|
|
||||||
|
To do this, add the `--main` flag:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ rails new rails_app_on_main --main
|
||||||
|
```
|
||||||
|
|
||||||
|
Toward the top of your app's `Gemfile`, you'll see that `rails` is pointed to
|
||||||
|
the `main` branch of their repo:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Use main development branch of Rails
|
||||||
|
gem "rails", github: "rails/rails", branch: "main"
|
||||||
|
```
|
||||||
|
|
||||||
|
See `rails new --help` for more details
|
||||||
|
|
||||||
|
[source](https://x.com/gregmolnar/status/1832720168264286571)
|
||||||
32
rails/validate-column-data-with-check-constraints.md
Normal file
32
rails/validate-column-data-with-check-constraints.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Validate Column Data With Check Constraints
|
||||||
|
|
||||||
|
A check constraint is a feature of database systems like PostgreSQL that allows
|
||||||
|
you to enforce rules about the data that goes in a table's column. As of Rails
|
||||||
|
6.1, ActiveRecord provides a way to add a check constraint via the DSL.
|
||||||
|
|
||||||
|
In this example, we want to ensure that the value going into the
|
||||||
|
reading_statuses.status column is one of four values. Nothing else besides
|
||||||
|
these four values should be allowed.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class AddReadingStatusTable < ActiveRecord::Migration[7.2]
|
||||||
|
def change
|
||||||
|
create_table :reading_statuses do |t|
|
||||||
|
t.references :user, null: false, foreign_key: true
|
||||||
|
t.references :book, null: false, foreign_key: true
|
||||||
|
t.string :status, null: false
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
add_check_constraint
|
||||||
|
:reading_statuses,
|
||||||
|
"status in ('started', 'completed', 'abandoned', 'already_read')",
|
||||||
|
name: "reading_statuses_valid_status_check"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
The `#add_check_constraint` method takes the name of the table and a SQL clause
|
||||||
|
that can evaluate to true or false for a given row. We can optionally include
|
||||||
|
the name of the check constraint (e.g. {table_name}_{column_name}_check) like
|
||||||
|
we've done above.
|
||||||
32
rspec/avoid-accidentally-disabling-pry.md
Normal file
32
rspec/avoid-accidentally-disabling-pry.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Avoid Accidentally Disabling Pry
|
||||||
|
|
||||||
|
I was recently working on a test that needed to mock an environment variable in
|
||||||
|
order to observe the behavior under test. I initially ended up with the
|
||||||
|
following lines in a `before` block.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
before do
|
||||||
|
allow(ENV).to receive(:[]).and_return("")
|
||||||
|
allow(ENV).to receive(:[]).with("API_SERVER_URL").and_return("localhost")
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
The idea was to create a "clean" `ENV` for the test and then layer in any
|
||||||
|
relevant environment variables from there.
|
||||||
|
|
||||||
|
This is a misguided approach for a couple reasons. One particular and
|
||||||
|
hard-to-debug issue is that this mocking of `ENV` accidentally disabled Pry
|
||||||
|
(i.e. `binding.pry`). So once I was having issues with my test, I couldn't even
|
||||||
|
inspect the code at runtime. It would skip right past any `binding.pry`
|
||||||
|
statement I added.
|
||||||
|
|
||||||
|
What happened is that [Pry (specifically `pry-rails`) looks for
|
||||||
|
`ENV['DISABLE_PRY_RAILS']`](https://github.com/pry/pry-rails/blob/d8d0c6d87a5b8a3e570e0c80910fb80068f3553c/lib/pry-rails.rb#L6)
|
||||||
|
and if that value is _truthy_ then it won't require the various `pry-rails`
|
||||||
|
modules.
|
||||||
|
|
||||||
|
The first `allow` has `ENV` responding with `""` which is truthy and will
|
||||||
|
result in Pry being disabled.
|
||||||
|
|
||||||
|
A more appropriate default would be `nil`. Also consider that there are many
|
||||||
|
ways to access `ENV`, such as `#fetch`.
|
||||||
33
rspec/configure-tests-to-run-in-random-order.md
Normal file
33
rspec/configure-tests-to-run-in-random-order.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Configure Tests To Run In Random Order
|
||||||
|
|
||||||
|
By default, an RSpec test suite is going to run in a predictable, sequential
|
||||||
|
order, every time.
|
||||||
|
|
||||||
|
When testing the parts of a complex Rails app that have all kinds of test data
|
||||||
|
that needs to be set up, I prefer to have my tests always run in a random
|
||||||
|
(repeatable with a seed) order. This way I'm more likely to catch sooner,
|
||||||
|
rather than later, bugs that are hidden by passing tests due to test data setup
|
||||||
|
that happens to work in a specific order.
|
||||||
|
|
||||||
|
RSpec can be configured to run tests in a random, seedable order in the
|
||||||
|
`spec_helper.rb` file.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.order = :random
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Whenever you run your test suite, the first thing you'll see is a message like
|
||||||
|
this:
|
||||||
|
|
||||||
|
```
|
||||||
|
Randomized with seed 7011
|
||||||
|
```
|
||||||
|
|
||||||
|
That seed number can be used to re-run the suite in a repeatable order when you
|
||||||
|
need to do so to track down an order-dependent failing test.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ be rspec --seed 7011
|
||||||
|
```
|
||||||
46
ruby/multi-line-comments.md
Normal file
46
ruby/multi-line-comments.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Multi-Line Comments
|
||||||
|
|
||||||
|
Ruby has an obscure syntax for creating multi-line comments.
|
||||||
|
|
||||||
|
In many languages, there is a multi-line comment syntax that looks something
|
||||||
|
like this:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/*
|
||||||
|
* multi-line comment in javascript
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
This gets used often in those languages.
|
||||||
|
|
||||||
|
In Ruby, the multi-line comment syntax is not something we see very often. It
|
||||||
|
is a departure from the single-line comment syntax and it also requires no
|
||||||
|
indentation.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.order = :random
|
||||||
|
|
||||||
|
# The settings below are suggested to provide a good initial experience
|
||||||
|
# with RSpec, but feel free to customize to your heart's content.
|
||||||
|
=begin
|
||||||
|
# These two settings work together to allow you to limit a spec run
|
||||||
|
# to individual examples or groups you care about by tagging them with
|
||||||
|
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
||||||
|
# get run.
|
||||||
|
config.filter_run :focus
|
||||||
|
config.run_all_when_everything_filtered = true
|
||||||
|
|
||||||
|
# ...
|
||||||
|
|
||||||
|
=end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Using the `=begin` and `=end` syntax (no indentation), we make everything
|
||||||
|
inbetween into a comment.
|
||||||
|
|
||||||
|
Though we don't see this too often, I did pull this example directly from the
|
||||||
|
`spec_helper.rb` file that RSpec generates.
|
||||||
|
|
||||||
|
[source](https://docs.ruby-lang.org/en/master/syntax/comments_rdoc.html)
|
||||||
44
ruby/skip-the-front-of-an-array-with-drop.md
Normal file
44
ruby/skip-the-front-of-an-array-with-drop.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Skip The Front Of An Array With Drop
|
||||||
|
|
||||||
|
I've long been familiar with Ruby's
|
||||||
|
[`Array#take`](https://apidock.com/ruby/Array/take) which is a handy way to
|
||||||
|
grab the first few elements of an array.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
> [:a, :b, :c, :d, :e, :f, :g].take(4)
|
||||||
|
=> [:a, :b, :c, :d]
|
||||||
|
```
|
||||||
|
|
||||||
|
But what if I want to skip those first four elements of the array and get what
|
||||||
|
remains. That is where [`Array#drop`](https://apidock.com/ruby/Array/drop)
|
||||||
|
comes in.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
> [:a, :b, :c, :d, :e, :f, :g].drop(4)
|
||||||
|
=> [:e, :f, :g]
|
||||||
|
```
|
||||||
|
|
||||||
|
How about a couple practical situations for use in a Rails app.
|
||||||
|
|
||||||
|
Here I want to segment out the first 6 books and whatever remains:
|
||||||
|
|
||||||
|
```
|
||||||
|
def index
|
||||||
|
@books = Book.order(created_at: :desc).limit(10)
|
||||||
|
|
||||||
|
@featured_books = @books.take(6)
|
||||||
|
@remaining_books = @books.drop(6)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, what about cleaning up all but the first of these duplicate records:
|
||||||
|
|
||||||
|
```
|
||||||
|
Book
|
||||||
|
.where(title: "The Murder of Roger Ackroyd")
|
||||||
|
.drop(1)
|
||||||
|
.each { |duplicate_book| duplicate_book.destroy }
|
||||||
|
```
|
||||||
|
|
||||||
|
The first record is ignored (dropped from the array) and the following records
|
||||||
|
are processed by the `#each` where they get destroyed.
|
||||||
28
unix/convert-svg-to-favicon.md
Normal file
28
unix/convert-svg-to-favicon.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Convert SVG To Favicon
|
||||||
|
|
||||||
|
The imagemagick `convert` CLI tool can convert an SVG file into a transparent
|
||||||
|
favicon (ICO) file with the different standard sizes.
|
||||||
|
|
||||||
|
Assuming the background that we want to make transparent is white, then include
|
||||||
|
`-transparent white` and then to resize the icon include `-define
|
||||||
|
icon:auto-resize ...`. Point to the `image.svg` to be converted and specify the
|
||||||
|
name of the output file (`favicon.ico`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ convert image.svg -transparent white -define icon:auto-resize=16,32,48,64,128 favicon.ico
|
||||||
|
```
|
||||||
|
|
||||||
|
We can then use the `identify` CLI to inspect the `favicon.ico` file to see
|
||||||
|
that the above worked.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ identify favicon.ico
|
||||||
|
|
||||||
|
favicon.ico[0] ICO 16x16 16x16+0+0 8-bit sRGB 0.000u 0:00.002
|
||||||
|
favicon.ico[1] ICO 32x32 32x32+0+0 8-bit sRGB 0.000u 0:00.004
|
||||||
|
favicon.ico[2] ICO 48x48 48x48+0+0 8-bit sRGB 0.000u 0:00.004
|
||||||
|
favicon.ico[3] ICO 64x64 64x64+0+0 8-bit sRGB 0.000u 0:00.004
|
||||||
|
favicon.ico[4] ICO 128x128 128x128+0+0 8-bit sRGB 99678B 0.000u 0:00.003
|
||||||
|
```
|
||||||
|
|
||||||
|
[source](https://www.joshmcarthur.com/2024/06/19/Auto-resizing-images-for-.ico-files.html)
|
||||||
Reference in New Issue
Block a user