matt swanson ๐Ÿ˜ˆ Profile Banner
matt swanson ๐Ÿ˜ˆ Profile
matt swanson ๐Ÿ˜ˆ

@_swanson

12,240
Followers
30
Following
1,228
Media
14,225
Statuses

๐ŸŽฏ Building ๐Ÿ”ฅ Ruby on Rails tips ๐Ÿ“ป โœŒ๏ธ All killer, no filler ๐ŸŠ Karl Pilkington is my spirit animal

Indianapolis, IN
Joined February 2010
Don't wanna be here? Send us removal request.
Pinned Tweet
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
I strongly identify as a Product Engineer. Not as: - Developer (I only like building user-facing things) - Full stack (I want to help with shaping, roll-out, strategy) - Entrepreneur (not interested in company building) - Indie hacker (like working with team, not into quick and
87
81
1K
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
25 year old me: don't write code comments, just use clear naming 35 year old me:
Tweet media one
348
417
6K
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
your javascript library could never
Tweet media one
64
96
2K
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
bro wtf is all this shit
Tweet media one
157
88
1K
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
The best book on how to get good Bet you've never even heard of it, much less read it...
Tweet media one
30
122
1K
@_swanson
matt swanson ๐Ÿ˜ˆ
3 months
this join table will save your startup $100,000
Tweet media one
57
83
1K
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
So much of SaaS is: build an API to wrap your database so that I can parse the JSON and put it into my own database
39
84
1K
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Use Tailwinds `tabular-nums` to keep numbers in tables, counters, etc nicely aligned
16
90
1K
@_swanson
matt swanson ๐Ÿ˜ˆ
5 years
๐Ÿคฏ Basecamp is building a fully-featured, in-browser email client...using a ridiculously small amount of JavaScript. A tiny keyboard shortcut lib, one polyfill, and boring old Stimulus/Turbolinks/Rails... ๐Ÿ™ to @dhh for generously shipping source maps, amazing learning resource
Tweet media one
25
124
984
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
The @t3dotgg Problem Teaching a generation of developers to race for quick dunks, ignore context when evaluating decisions, outsource thinking to who has the most internet points, and then crybully if anyone disagrees RE: Exiting the cloud I'm not sure if Theo has actually read
86
84
938
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
@mitchhanberg Comments are bad when other people write them. Comments are good when I write them. ๐Ÿ˜ˆ
15
28
938
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
My brother is a React engineer. He is insanely gifted. We were looking at this data table with inline editing the other day and I asked him what it would cost to build it today with Rails. I will never forget his answer... "We can't, we don't know how to do it."
25
42
943
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Building a b2b SaaS product is 95% HTML forms and background jobs so get really fucking good at those
32
57
834
@_swanson
matt swanson ๐Ÿ˜ˆ
3 months
Our entire product is powered by these 30 lines of boring Rails code
Tweet media one
27
25
765
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
Tailwind is so fucking good
32
38
623
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Tweet media one
25
49
584
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
the funniest microservice i ever had the pleasure to work with was the NavBarService in a suite of 3-5 web apps you had to make a separate http call to get the contents on the nav bar. when it was down or timed out, you lost the ability to click "Home"
37
20
567
@_swanson
matt swanson ๐Ÿ˜ˆ
2 months
People are out here depending on an external service and paying PER-REQUEST for API calls to do rate-limiting... Rails 7.2 lets you do all that with your existing app infra for free with one line of code
Tweet media one
36
44
567
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Sometimes I write a TODO comment when we are waiting for a library to release a new version to fix a workaround or patch But even better is a test that will fail when you've upgraded the library so you remember to go back
Tweet media one
24
44
461
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
Three Rails methods you'll kick yourself for not knowing ๐Ÿคฆ
Tweet media one
20
82
457
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
I saw @JoshWComeau link this beautiful site of conic CSS gradients: Just a few lines to add conic gradients to your Tailwind config!
Tweet media one
3
51
436
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
25 year old me: "ooh a new gem for authorization with a quirky name and terse DSL" 35 year old me:
Tweet media one
31
14
435
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Building a b2b SaaS product is 95% forms and background jobs so get really fucking good at those
14
32
404
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
You probably knew about querying dates in ActiveRecord using a Range, but did you know about the Rails `all_month` helper? ๐Ÿ’…
Tweet media one
27
46
405
@_swanson
matt swanson ๐Ÿ˜ˆ
11 months
Is there any reason to use Redis over SQL in 2023? SQLite, LiteFS, and huge SSDs for cheap might have flipped the equation
74
14
396
@_swanson
matt swanson ๐Ÿ˜ˆ
3 years
If you type `cal 3 2022` into your terminal, you can get an ASCII calendar (March 2022) that you can add as a comment to your tests Extremely helpful when doing date math
Tweet media one
13
74
381
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
Building a b2b SaaS is basically 95% forms and background jobs so get really fucking good at those
18
28
373
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
Some Rails methods you'll kick yourself for not knowing ๐Ÿคฆ
Tweet media one
14
47
344
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
Unpopular advice for junior engineers: - Work in-person at a project-based consultancy (regardless of tech stack) - Use open source, but do not try contributing - Editor fiddling, vim, exotic terminals are a total waste of time - Anything beyond "git 101" doesn't matter
27
36
334
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
๐Ÿงฎ Ruby's Enumerable #tally is so underused It's great for quickly exploring your data without writing a bunch of loops and counters
Tweet media one
12
28
330
@_swanson
matt swanson ๐Ÿ˜ˆ
9 months
๐Ÿ•๏ธ Campfire source diving: soft-deleting users Many apps reach for a gem to handle soft-deletion of records. In the case of Campfire, you want to support deleting a user, but you don't want to lose all the messages. Other tools like GitHub use a "ghost user"
Tweet media one
13
17
319
@_swanson
matt swanson ๐Ÿ˜ˆ
3 years
Huge ๐Ÿคฏ today: built the historically super annoying "dynamic list of form fields" in Rails without any JS, Stimulus, weird hidden markup, or new AJAX endpoints Key point: you can use turbo-stream elements in normal views!
Tweet media one
Tweet media two
16
31
316
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Love to see @t3dotgg pile into a github repo when you know his ass would make five videos about "open source harassment" if it was his project
11
9
309
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
When I first started doing web development, I thought I hated ORMs because I was using tools like NHibernate and drowning in a sea of "projection mappings" and DTOs Then I found ActiveRecord and I've never wanted to use anything else โ™ฅ๏ธ
Tweet media one
32
12
301
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Skeleton loaders with Rails + Hotwire + Tailwind Use a <turbo-frame> with `lazy: true` and put the loading state as the initial frame contents. Add some rough shapes and use Tailwinds `animate-pulse` to give it a subtle pulsing effect When the frame scrolls into the viewport,
Tweet media one
Tweet media two
Tweet media three
13
14
303
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
"This core concept in Rails? You should not use it at all!" ๐Ÿคฆ Some people have really lost their way when it comes to code design
Tweet media one
64
20
301
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
I don't think you can write this any cleaner than in Rails
Tweet media one
14
17
299
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
๐Ÿ•ต๏ธ New in Rails 6.1: find records missing associations with `where.missing`
Tweet media one
7
55
296
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
๐ŸŽฃ Automatically cast params with the Rails Attributes API
Tweet media one
9
36
288
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
let him cook
Tweet media one
11
7
281
@_swanson
matt swanson ๐Ÿ˜ˆ
3 years
It's hacky but this might help you if you're working with turbo-frames: add this CSS in development ๐Ÿ˜Ž
Tweet media one
Tweet media two
10
31
280
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
You can define helpers in your .irbrc to quickly load records (like your own user account) in the Rails console
Tweet media one
13
18
276
@_swanson
matt swanson ๐Ÿ˜ˆ
9 months
๐Ÿ•๏ธ More Campfire source diving: flash messages CSS animation + `animationend` event + self-destructing Stimulus controller to show the flash message then fade it out after 5 seconds. No setTimeout! Don't think I've ever seen this approach before
Tweet media one
18
12
273
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
I very rarely use an external gem for APIs anymore. Too much hassle (upgrades, weird generated code, not following Ruby/Rails idioms) for the cost. You can wrap most APIs in less than 50 lines of code, especially if you only need to interact with a small subset of the endpoints
Tweet media one
22
13
271
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
๐Ÿง  Key takeaway from @adamwathan Full Stack Radio interview with @dhh on Hotwire: start simple at the top of the stack and layer on *as you need it* Each page in your app will have different needs and may not warrant going all the way down the stack every time.
Tweet media one
7
40
271
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
๐Ÿงฎ Enumerable #tally is still underused in Rails apps It counts the occurrence of each element in a list
Tweet media one
8
23
267
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
๐Ÿ‘ฎ @dhh has teased "console1984", a new gem that helps you access customer data from the console in a responsible manner... Fun Friday hack: build a crappy version in ~30 lines of Ruby
Tweet media one
Tweet media two
11
18
269
@_swanson
matt swanson ๐Ÿ˜ˆ
9 months
An elegant "capped collection" from the Campfire code User searches are stored as database records, but after each one is created, destroy any that are outside of the most recent 10 (nice usage of the Rails 7 `excluding`!) Would have maybe expected Kredis for this, but callback
Tweet media one
7
15
265
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Two years into this codebase and still loving this pattern for organizing features by module Keeps related methods together and makes it easier to find relevant code as the codebase grows. Plus I can separate out test files by feature.
Tweet media one
22
13
257
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
It's little things like this that make you never want to leave Rails
Tweet media one
14
13
234
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
๐Ÿ… Unpopular advice for junior engineers: - Work in-person at a project-based consultancy (regardless of tech stack) - You don't need to contribute to open source - Vim and exotic terminals are a waste of time - Skip anything beyond "git 101" for now - YouTubers are not mentors
28
29
251
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
It's wild that in the past 15 years there hasn't been a better Ruby/Rails talk than this:
13
33
247
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Whenever possible, return chainable ActiveRecord relations instead of arrays when doing complex queries. If you need to break out early, use `Product.none` If you need to drop down to Ruby, collect the ids and re-query
Tweet media one
11
20
245
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
๐Ÿ—œ๏ธYou probably want `compact_blank` most places you are using `compact`
Tweet media one
9
29
246
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
๐Ÿ›‘ Stop: using Date.parse and to_i โœ… Start: using Rails attributes API for casting
Tweet media one
4
23
244
@_swanson
matt swanson ๐Ÿ˜ˆ
3 years
React? Vue? Nope. It's just Rails `button_to` inline forms and a <turbostream> response ๐Ÿ˜Ž
8
14
239
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
I always forget that you can sort variables alphabetically straight from VS Code ๐Ÿคฆ
15
13
223
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
It's been 3 days since a video said "Sadly the [Rails] creator seems pretty done with change and he refuses to acknowledge a lot of things that have pushed the web forward since his time" Meanwhile Bun support for Rails was merged ๐Ÿคท
@dhh
DHH
1 year
Love the work that @bunjavascript is doing to simplify life in the JavaScript world. Happy to merge @jmeller 's patch to add support for it in jsbundling-rails โœŒ๏ธ
17
79
1K
8
14
224
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Hotwire Strada will be shown at RailsWorld ๐Ÿ‘€
Tweet media one
11
32
225
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
โšก๏ธ Add this `.irbrc` file and your Rails console will show a colorized banner with the environment Never accidentally run something in a production-connected Rails console again!
Tweet media one
12
48
225
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
I was radicalized against Big Javascript when I had to write the most mundane settings page in an app and we had to use React + Redux + Jest and it took 2 weeks
23
9
214
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Did you know you can test a multi-user flow with Capybara and Rails system tests? Try the `using_session` block to switch between sessions. I've used this a ton to set workflows like User A submits something, User B approves, User A should see it as completed
Tweet media one
4
22
212
@_swanson
matt swanson ๐Ÿ˜ˆ
3 years
๐Ÿ“ง Add a more personal touch to your Rails mailers with `email_address_with_name`
Tweet media one
11
18
210
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Use a Rails initializer to stop your app from booting if it's missing required environment variables. (Make the name `initializers/01_ensure_env.rb` to make sure it runs first)
Tweet media one
11
11
206
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Please remove any code you wrote for displaying phone numbers and use the Rails built-in instead ๐Ÿ™
Tweet media one
5
21
201
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
> reads one paragraph of a blog post > livestreams creating spam PR to 700+ people > pulls up dunk tweets from people that aren't involved > "I am proud of my work" DONT HARASS PEOPLE THO ๐Ÿคก
8
10
199
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
What is your favorite Ruby/Rails method? Mine is probably `compact_blank` in ActiveSupport If removes all `blank?` values from arrays and hashes so you can confidently chain additional collection methods
Tweet media one
18
19
196
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
๐Ÿคผโ€โ™‚๏ธ Sort ActiveRecord models by an enum value (in SQL!) using `in_order_of` Super handy to float results to the top of a list
Tweet media one
4
25
195
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
I can't believe how "egregiously fucked over" I am without TypeScript definitions for Turbo. Really feeling the "user hostile dickwaddery" today. What's that? You didn't realize that you just import the library and aren't calling it directly?
Tweet media one
9
9
188
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
If you don't deploy on Fridays (you care about your engineers), do you also not deploy: - Late in the day (on-call) - In the morning (west coasters not up yet) - Mondays (kickoff calls), etc This thinking leads to one 15min window every 2nd Wednesday when you actually ship
21
24
193
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
Really digging this pattern for organizing different 'features' of a model. Keeps related methods together and makes it easier to find relevant code as the codebase grows. Plus I can separate out test files by feature.
Tweet media one
13
17
191
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
The amazing part is that I built this with an HTML form and I didn't need a serverless edge compute function to transpile my runes into typesafe headless components!
6
4
188
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
You can query recently created records with an endless range instead of dropping down to raw SQL fragments
Tweet media one
7
17
184
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
This is the ideal Rails view. You may not like it, but this is what peak performance looks like.
Tweet media one
16
8
186
@_swanson
matt swanson ๐Ÿ˜ˆ
5 years
๐Ÿ‘‹ย Working on a new project: I've been using this unsexy, "boring" Rails stack for close to a year at work and think it's compelling. Will share what I've found for folks *not* working at the extremes of either scrappy MVP or mega-corp.
14
28
182
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
Programmers coming from other ecosystems are often shocked at much Ruby looks like pseudocode. Instead of using methods like `gsub` or `chomp`, you can write super readable alternatives with `delete_prefix` and `delete_suffix`
Tweet media one
5
14
181
@_swanson
matt swanson ๐Ÿ˜ˆ
8 months
I didn't have time to write you a short answer, so I wrote you a long one - Often people feel the desire to have "attribute-level" validations because they don't have enough controllers. The 1:1 mapping of resource and controller is great early on but it is actively harmful if
@bjessbrown
Jess Brown
8 months
Usually people write a blog post to share something they learn. I'm flipping that. I need you to teach me something. Know anything about authorization? Help me out...
3
0
21
11
18
183
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
we are so back
Tweet media one
10
8
182
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
One of the best ways to level up your Rails app design is to have more controllers and namespaced models so you can stick to REST conventions The missing ingredient is to use a `Scoped` concern to slim down the controllers and centralize logic
Tweet media one
10
9
178
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
I always forget that you can sort variables alphabetically straight from VS Code ๐Ÿคฆ
15
27
177
@_swanson
matt swanson ๐Ÿ˜ˆ
11 months
A sneaky but potentially very bad mistake: reusing `REDIS_URL` in Rails for too many things You probably do not want: Kredis, Rails cache, ActionCable, Sidekiq, etc to be using the same Redis database These tools all have different eviction policy needs and storage
14
19
172
@_swanson
matt swanson ๐Ÿ˜ˆ
11 months
Don't get the hate on , it's pretty much all upside: - bunch of new 37s code/libraries will be available to read/learn from - self-hosted tools for small teams that you could use - if it works, pressure on cloud vendors for price reductions - someone else
14
5
170
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
โš“๏ธ Combine `redirect_to` with the `anchor` option after editing a record from a list to keep your scroll position
Tweet media one
3
16
165
@_swanson
matt swanson ๐Ÿ˜ˆ
3 years
๐Ÿงฎ Quickly explore your data with Ruby Enumerable methods `uniq` and `tally`
Tweet media one
8
16
165
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
โ˜๏ธ Today's "of course there's a Rails helper for that..." `link_to_unless_current` - renders an <a> tag unless the href is to the current URL. Handy for nav bars or tabs!
Tweet media one
6
22
158
@_swanson
matt swanson ๐Ÿ˜ˆ
2 years
How can you not love Ruby/Rails? I mean honestly?
Tweet media one
Tweet media two
11
10
155
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Never build a seach box without this feature
Tweet media one
9
12
158
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
Stop writing `i % 2 == 0` or `if i.odd?` in your view loops. Next time bust out `cycle` ๐Ÿšฒ
Tweet media one
5
15
158
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
10+ years of using Rails and still finding new features. Used Association Extensions this week so I could add a convenience finder method on a has_many
Tweet media one
Tweet media two
6
15
156
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
In the Rails console (or IRB), you can use `_` to get the result of the last run command ๐Ÿ˜ฒ
Tweet media one
11
18
155
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
Ever accidentally email 100s of real customers from your staging/demo server? Couldn't be me. Add this to your Rails app to intercept and re-route all emails to your own account.
Tweet media one
7
14
154
@_swanson
matt swanson ๐Ÿ˜ˆ
7 months
IMO a Hotwire app should be like 85% Drive, 10% Frames, 5% Streams -- often I see people (including articles/guides) that have it almost completely flipped.
20
6
155
@_swanson
matt swanson ๐Ÿ˜ˆ
3 years
I would love to see a revived "Rails Rumble" (48 hour build the coolest thing with Rails virtual hackathon) in 2021. Anyone else?
16
9
154
@_swanson
matt swanson ๐Ÿ˜ˆ
9 months
One project for this year is to write the best resource for building Rails UI with ViewComponents What else would you like covered?
Tweet media one
26
5
153
@_swanson
matt swanson ๐Ÿ˜ˆ
1 year
I've never once in the many years I've been doing Rails development regretted extracting a controller. I've never wished my controllers were bigger, I've always wished I had more of them and they were smaller.
8
13
154
@_swanson
matt swanson ๐Ÿ˜ˆ
10 months
2024 Rails "unsolved problems" if you're looking for inspiration for a tool/content/course - Managing test data effectively beyond the basics: factories and fixtures both have big drawbacks, could be reimagined. what do other ecosystems do? - shadcn components as server-side
12
5
153
@_swanson
matt swanson ๐Ÿ˜ˆ
2 months
Happy Friday, add "req/sec" to your muted words today and ship something to customers
9
8
151
@_swanson
matt swanson ๐Ÿ˜ˆ
4 months
๐Ÿ“˜ Writebook source-diving: Scoped module Common DHH/37s pattern here, but still underused -- pull common controller code for looking up a record into a `Scoped` module Use that for nested controllers: In Writebook, there is `BookScoped` to handle the common operation of
Tweet media one
10
7
152
@_swanson
matt swanson ๐Ÿ˜ˆ
4 years
๐Ÿ“Œ I think the most underrated #Rails helper is `dom_id` Two things I use it for regularly: deep linking (anchor links, redirect back locations) and for targeting elements in browser tests
Tweet media one
17
26
152