Tailwind CSS

Summarized using AI

The Empowered Programmer

Justin Searls • September 26, 2024 • Toronto, Canada

In his talk titled "The Empowered Programmer" at Rails World 2024, Justin Searls explores how the Ruby on Rails framework enables developers, particularly solo developers, to execute formidable projects efficiently. He reflects on his journey in software development within the context of building an app for his wife, Becky, who transformed her fitness program into a software platform. Searls emphasizes how Rails' expanding functionality empowers programmers, allowing them to take ownership and sustain projects without extensive resources. Throughout his presentation, he highlights six key principles that characterize an empowered programmer:

  • Courageous: Emphasizing the 'Cone of Uncertainty,' Searls advocates for prioritizing riskiest features first. He illustrates this with his prior experience developing a video hosting feature, where he initially faced fear but overcame it through experimentation with tools like Active Storage.

  • Resilient: Searls discusses the importance of maintaining software in the long term and describes how Rails 7 has introduced features that reduce future regrets, notably in authentication processes and usage of modern CSS frameworks like Tailwind.

  • Efficient: Highlighting his efforts to streamline user workflows, he explains how he implemented a Readiness Checker to manage production-ready programs without burdening Becky with cumbersome validations.

  • Dextrous: Searls shares key decisions in his tech stack choice, including the decision to minimize user data storage and the embrace of ephemeral data management to keep operational costs predictable.

  • Disciplined: He stresses the necessity of restraint in feature development, sharing anecdotes about limiting user interface complexity to maintain focus on key functionalities.

  • Meticulous: Searls wraps up by emphasizing the importance of detail-oriented design and code maintainability, showcasing the value of utilizing tools that naturally align with Rails workflows.

His conclusion accentuates that combining these six traits with a solid understanding of Rails functionalities allows developers to create robust applications efficiently, reducing pressure while still delivering quality results. Searls hints at his future endeavors as this marks his final conference presentation, leaving a lasting message about the power of individual developers in leveraging Rails for substantial applications.

The Empowered Programmer
Justin Searls • September 26, 2024 • Toronto, Canada

In 2019, Justin Searls gave a talk, "The Selfish Programmer" all about building a Rails 5 app as a one-man show. Now, he is back to share how he made a new app that's twice the size but felt like half the work. You'll learn how Rails includes more batteries than ever, when sticking with omakase pays off, and why scaling back a team doesn't have to mean slowing down.

Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/

Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/

Rails World 2024

00:00:10.120 Well, it's a day of firsts! That's my first ever walk-on music. They didn't let me pick a track.
00:00:19.640 Welcome! I'll give you just a few moments to sit down.
00:00:25.800 Alright, time’s up! Hi, I'm Justin. You can find out all about me and everything that I do at my homepage, justin.s.co, or email me at [email protected].
00:00:31.640 Hopefully, it's pretty obvious today is a big day! It's been 10 years since my first Rails World talk. I spoke at Rails World negative 8 in 2014 in Chicago.
00:00:42.160 My career really peaked at Rails World negative 5 when I was invited to keynote in Phoenix in 2017. I'm really enjoying Rails World 2 so far, and I hope you are too.
00:00:50.039 You might remember me for having co-founded Test Double with Todd Kaufman back in 2011, and amazingly it has grown to be one of the most trusted Ruby and Rails consultancies in the world.
00:01:02.440 If anything I talk about today sounds like something you'd love to see with your team, please reach out, and let's talk about how maybe Test Double can help you.
00:01:15.520 Last week, I also celebrated the one-year anniversary of Searls LLC, where I serve as co-CEO with my brother Jeremy. That makes me the Chief Justin Officer, responsible for most of the Justin-related things in the business.
00:01:26.400 This is Becky, sitting right there. She believes in fitness and started a business a couple of years ago called Build with Becky.
00:01:33.200 How it works is that she builds strength training programs for people and then distributes them manually to all of her subscribers, which quickly presented a scaling issue.
00:01:42.160 Like a lot of founders, she decided to scale with software and expanded the brand to incorporate other potential services, which is now actually called Better with Becky. I guess that means we're making a platform play!
00:01:55.960 Becky is not a programmer and couldn't afford to pay someone to build it for her, so that's how I got recruited as her first CSO.
00:02:01.320 If you're not familiar with fitness industry jargon, that means 'Chief Supportive Husband Officer.' So, I built her an app, and that's what brings me to this stage to talk to all of you today.
00:02:14.000 A few years ago, DHH declared that Rails was the 'one-person framework' because it's so productive that even just one person can do something great.
00:02:21.200 I'm one person, so I figured I should use Rails for this app. In this presentation, I'm going to talk about some of that. I really treated this app development as an opportunity to test David's hypothesis.
00:02:36.519 I wanted to ask how does Rails empower me as a solo developer?
00:02:43.560 At the outset, I told Becky she could have as much of my time as necessary to build the app, but I wouldn't let maintaining it become my forever job. Speaking of endings, I have an announcement: this is going to be my final conference presentation. My life has been transformed by the opportunity to speak in front of people like you for so long.
00:03:07.799 But I’ve decided I need to make room in my life for new pursuits. A lot of preparation goes into this, and it’s just a month of nerves.
00:03:15.000 So next time I clock an anxious person, I’m going to clap in their face to calm them down.
00:03:20.920 Today we're going to talk about the six key muscle groups of the Empowered Programmer and discover different ways that Rails helps us get stronger as developers.
00:03:27.640 The Empowered Programmer, first and foremost, is courageous. Let's begin by exploring how even some of the lesser-known features of Rails can make ambitious features achievable for a solo developer.
00:03:39.120 Let's start by asking: what’s the best way to prioritize a backlog? I prefer something called 'The Cone of Uncertainty.' It looks like this.
00:03:46.400 The beginning of any project is when we know the least, so it has the highest risk. As we build software, things become clearer, and that risk diminishes. The cone gradually shrinks before we reach the point of no surprise, where the work is finished and we can all look back, absolutely no one is surprised because we all know how it went.
00:04:06.720 Different projects have different shapes; you could defer the scary bits to the end or pull risks forward and address them right away. You can probably guess which shape results in the best outcomes. The question is, how do you control the shape of the cone?
00:04:29.960 It requires changing how we measure progress. Is progress how much code we ship or how many features we deliver? In my view, it’s actually about how much certainty we gain as we tackle the riskiest features.
00:04:42.080 Planning starts then, instead of looking at normal priority or what’s in the MVP. Instead, we should be asking, 'What am I most afraid of?' For this application, it was video. There's a lot of hosted video in the app, and if you think of a typical form field, there's just not a lot of risk.
00:05:06.720 Even if you have a photo upload or something, you can probably get away with just stashing that in the database. But uploading, processing, and hosting video, that felt really risky to me.
00:05:19.199 So, here's what risk-first planning looks like: first, identify the scariest feature. Then, make it safe for yourself to make a mess, and then you make a mess. Eventually, you figure it out, and it’s not so scary anymore.
00:05:38.400 That’s why I made an Instagram clone for my wife. I know it sounds ridiculous, but I needed a safe and low-stakes way to learn how to host video. My career has taught me that side quests are one of the most effective ways to learn a new skill.
00:06:04.360 This is what Becky’s Instagram looks like, and this is Becky Graham. Everything that she posts here syndicates to Instagram, so she can create content in a place that she owns without disappearing from the internet.
00:06:10.880 Now, let’s do a quick demo of the admin to show off the Active Storage functionality. I started with a basic form and a file input. Okay, so let’s pick out a video at random.
00:06:36.520 I had no clue what to do when the user clicks save. Fortunately, I didn’t have to worry for too long because I already spoiled it! I selected Active Storage because Rails ships with it since 2016 with Rails 5. It has improved a ton since then.
00:06:58.479 Aaron and I actually paired and fixed a few bugs earlier this year, so it still has its rough edges. The upload story is complex enough that I had to draw a diagram.
00:07:11.440 What happens when you click save? First, the file itself is directly uploaded to S3 using JavaScript, and then the form is submitted to the server, which initiates a background job called 'analyze job.' That job downloads the video from S3 to create thumbnails and processes it as needed.
00:07:37.280 That might sound like a lot, and it is a lot, but you know, video is complicated. Trust me, Active Storage handles all the heavy lifting, and it's really nice.
00:07:58.320 So, the payoff is that when you click save, the video is uploaded and viewable. It may not be super exciting, but that’s not the point— it doesn’t feel scary anymore!
00:08:12.599 Unfortunately, implementing Active Storage in an app is a topic much bigger than I have time for today, so I wrote a post outlining my lessons learned, and you can check it out after the talk.
00:08:28.840 The truth is, it takes courage to slow down when you feel pressure to go faster. Slow makes smooth and smooth makes fast, so yeah, could I have solved this without Active Storage? Sure.
00:08:47.640 But Active Storage helped me overcome my fear because so many other people trust it for their apps. Next, the empowered programmer is resilient.
00:09:07.200 Let’s take a tour of different new features in Rails that make things far more maintainable for developers in the long term. My main goal in life and in development is to minimize future regret. That's why I get on stage.
00:09:40.039 Rails 7 helped me avoid three areas where I’ve had regrets in the past.
00:09:42.000 Let's start with authentication and why I decided on email-based login. Everyone has an opinion on login strategy.
00:09:52.120 You might consider passwords, OAuth providers, pass keys, or email. But when users forget a password, you need a trusted email. If an API goes dark, like, you better hope you have their email.
00:10:05.320 If a pass key is created on an iPhone and the user can't log in on Windows, they’re going to contact support by email, so the lowest common denominator is email. Why complicate it?
00:10:15.640 Sure, something is going to defeat email someday, but it’s not going to be my little app. My favorite feature of Rails 7.1 was a couple of methods: one generates a secure token for a model, and the sister method finds it by token.
00:10:27.760 With just these two, you can implement email-based authentication. It looks a little like this: I can configure a 30-minute token in a model, and in a login controller, generate that token to pass it off to a mailer.
00:10:37.959 In the email, you can render a link with the token as a query param, so when the user opens the email and clicks the link, it triggers a different action on that controller to authenticate the user.
00:10:48.320 It’s so easy that I sometimes question its security, but I’ve been told it’s secure, so please don’t hack me.
00:11:05.320 For CSS, Rails now makes it incredibly easy to adopt Tailwind, which is remarkably easy to maintain.
00:11:13.040 Here’s the app’s login page: note the effortlessly rounded corners. Making a nice-looking webpage is challenging, but the true measure of success is trying to change your CSS three years later.
00:11:24.840 For example, if you have an old form that you forgot making and need to add margin above a button, you might find your markup looks like this.
00:11:34.480 You end up searching through for classes tied to those elements, making changes, and worrying that you've broken something else along the way.
00:11:46.160 The three-step process to updating legacy CSS involves finding the rule, making the change, and then exhaustively testing every page on every device. Not easy!
00:12:01.640 Tailwind replaces this arbitrarily expressive CSS with predictable and familiar utility classes. It allows you to significantly reduce the complexity of CSS rules.
00:12:15.640 Whenever I start a new app, I choose Tailwind, and if you’re upgrading an existing app, you can add it after the fact.
00:12:28.240 Lastly, let’s look at the solution to many of my JavaScript problems: Import Maps. One thing I dislike about email-based login is when I type in my email and realize I’m actually on the registration page.
00:12:40.640 So I have to go click login and then retype the email because I clicked the wrong option. If you want to fix that, you’ll need JavaScript, and surprisingly, I’ve loved building stuff with JavaScript.
00:12:54.399 Early on, I had a rough decade with JavaScript, but lately, I’m back at it thanks to Import Maps. Rails 7 lets you load raw JavaScript modules directly without needing a build step.
00:13:10.200 It’s turned on by default, so there’s nothing for you to run, but if you’re upgrading an old app, you can run the installer and add stuff.
00:13:24.000 A few tips for newcomers: you can vendor packages by running import map pin, which will fetch and put it in source control.
00:13:36.120 Make sure that you serve those assets on a CDN with HTTP/2 since there are many tiny requests that would otherwise be TCP requests.
00:13:50.720 Committing packages feels a bit gross, so it’s a healthy pressure to depend on fewer third-party JavaScript libraries. No build is simpler than no build, and you'll have a lot less to worry about already three years from now.
00:14:04.240 Thanks to enhancements like these, I’m confident that future me will be able to maintain Better with Becky for years to come.
00:14:21.120 The empowered programmer is also efficient when conventional approaches would slow your users down. Rails lets you go off the rails and take shortcuts.
00:14:37.200 I’ve always hated when things take too long, and this project revealed opportunities for improvement in Becky’s workflow.
00:14:50.280 Becky has spent a lot of time each month trimming videos, creating documents, fighting with spreadsheets, and emailing things out manually. My sense was she could achieve all the same goals in a whole lot less time.
00:15:06.760 One way I save her time in the app is by turning off a bunch of validations. This is a list of Becky’s workout programs, and instead of validating at save time, I built a custom Readiness Checker that gives a red-green status check of whether that program is ready to roll out to production.
00:15:24.320 Becky prefers to go bottom-up when she starts a program; she dives straight into the workout, and the program upon which that workout depends gets created automatically.
00:15:38.839 Additionally, when she goes to the first block of the workout, it happens again—now the workout relies on that block to be autocreated.
00:15:54.080 Any good Rails developer would look at that and say, 'Persisting stuff when you click a link is not very RESTful!' But everything in life is a trade-off.
00:16:06.240 To me, the user experience matters more in this case. It's not enough to just get out of your power users' way; there are things you can invent to supercharge their productivity.
00:16:18.240 For example, I’ve got these Hotwire combo box lookups where she refers to an associated model in a form. A little stimulus controller I wrote generates a link that opens the edit view of that same model in a new tab, so she doesn’t have to search for it.
00:16:34.800 When writing by hand, Becky abbreviates everything, so we leverage that by supporting her shorthand syntax when searching for movements. I don't know what this means, but it doesn't matter because this app isn’t for me.
00:16:49.520 If you prioritize something like this, your users will love you—even if they're not married to you! To be honest, my favorite feedback is that I’ve saved somebody time.
00:17:02.560 Because Rails doesn’t mind when I start off going off-road, my customers can get more done with less work. The empowered programmer is also dextrous.
00:17:14.240 If Rails' default would zig where my application needs to zag, it’s great that Rails makes it easy to swap things out. Knowing when to break from conventional wisdom is important.
00:17:30.240 Cal, Docker, and self-hosting are all things I won’t talk about today because I’m more than happy with Heroku. My architecture starts with the Heroku app server.
00:17:44.560 It’s backed by their managed Postgres, I use S3 and CloudFront to serve assets, and also use AWS for sending emails. I actually had to look that up because I set it up in January and haven’t thought about it since, so that’s a good sign!
00:18:00.560 Another unusual thing about this app is that it goes out of its way to avoid storing user data unnecessarily. Most apps would store everything by default; every set, rep, and weight would be separate database rows.
00:18:15.440 They’d probably realize they never have much use for that data and watch their costs skyrocket in proportion to usage. I've seen too many curves where revenue starts picking up, and costs start ballooning.
00:18:29.480 As programmers, we add complexity based on assumptions of what others need, so I try to listen to how customers speak about the features they want. It reveals opportunities to simplify.
00:18:46.240 When Becky talks about working out, she emphasizes mind-muscle connection and setting weights based on factors the app can’t know about, alongside a perceived level of effort rather than a prescribed amount of weight.
00:19:01.280 One day, I asked her what the app would do with all these weights that people are entering, and she couldn’t think of anything. So I got rid of it.
00:19:15.640 The new approach is that the app only tracks ephemeral state during a workout. It throws it into a JSONB column and, after the workout finishes, exports the important bits permanently and deletes the rest.
00:19:32.520 The JSONB looks like this: some stuff I need to remember until the next workout, some that I want to remember forever, and the rest can be discarded safely.
00:19:47.320 Considering the new app's data usage, I’m confident that once we generate a ton of revenue, costs should remain mostly flat. But if you all want to subscribe simultaneously and test that theory, that’s fine by me!
00:20:01.600 Good design means throwing overboard things that other people assume they need. Now, regarding system tests, another unusual thing I do is that I’m using Playwright instead of Selenium.
00:20:14.720 David recently wrote a post talking about how sporadic test failures are a massive drain on productivity. Selenium itself is very slow, and you might realize that this slowness encourages us to write brittle assertions.
00:20:30.000 In system tests, a driver automates browser actions and makes assertions waiting until the browser finishes doing stuff, satisfying the assertion before the test script continues.
00:20:48.360 If Selenium is slow during development, assertions may execute after the browser finishes, resulting in a flaky test.
00:21:05.560 If that pass occurs locally while writing the test, you won’t know if it passes before the browser action takes place.
00:21:20.080 The ironic cause of flaky builds is that Selenium actually runs faster in CI because it's headless. Fortunately, Playwright exists as a robust alternative, operating at a lower-level protocol.
00:21:35.440 The short version is just use Playwright. You can install that gem and change three lines to see all the test failures; those are all your flakes just failing for you now, so go fix them.
00:21:54.480 Since switching, the only time my build has failed is when Stripe checkout goes down, which is separately concerning but not my problem.
00:22:08.880 Once you work on a few apps, you find yourself much more comfortable swapping things out as needed. The empowered programmer is also disciplined.
00:22:19.760 We can learn from Rails by being more opinionated in our design. Focus on building only what matters and ignore the rest.
00:22:39.240 I believe that good software gets updates forever, but great software is designed, built, and then just works. We need more practice learning how to say no.
00:22:59.640 Vision is the easy part. I can have a brilliant idea in the shower, but executing that vision requires months of constant vigilance and saying no to distractions.
00:23:06.720 For example, I was adamant that we limit user-facing features. No to a more tab, hamburger icon, or ellipsis button in the UI.
00:23:22.440 Instead, I pulled out a whiteboard and drew the three tabs I knew we needed, turning it around to Becky to let her pick wisely because she only gets five.
00:23:35.040 We eventually landed on those answers, and the tab bar looks like this with the five tabs. If you look now, the same tabs apply.
00:23:44.440 So, we have five in February, five in June, and five in September. Yes, that was arbitrary, but this is what people mean by a liberating constraint.
00:23:50.800 It strengthens the product. This is what the membership program summary looks like. While it took me all afternoon, I used CSS grid to create this pretty little summary of a workout.
00:24:06.000 When I showed it to Becky, her first reaction was, 'Can I have a PDF version?' Before I could respond, she said she actually needed a second version of that PDF too.
00:24:26.720 Exhausted at that point, I immediately said no, then tried to find a reason. I said I didn’t want to deal with fancy PDF engine maintenance.
00:24:39.440 Fortunately, CSS makes this possible with media queries. Tailwind makes it easy too; it has a print variant where you just say print colon and any utility class.
00:24:54.800 I was delighted to find out that within 30 minutes of using print colon, I could make the printout look good enough for Becky, and then the project schedule wasn’t derailed.
00:25:09.680 Another day, she mentioned users need to search for movements and equipment, which is reasonable, but I was drunk with power at that point.
00:25:19.560 I reflexively replied, 'No fancy search features, no pagination, no infinite scrolling UI stuff!' Instead, I said, 'Let’s load them all until it poses a problem.'
00:25:33.919 This actually worked because there are only several hundred things, and it only took a few adjustments like lazy loading images.
00:25:49.679 If you’ve never lazy-loaded an image, here's a tag doing so—very simple! It’s worth doing.
00:26:03.760 The second thing I did was utilize fragment caching in the view layer. Secret: I’ve never used caching in Rails since I started playing in 2005, so this was brand new to me!
00:26:15.640 If you're iterating over a relation of movements, you just wrap it in a cache block, passing the thing that you know defines the cache key, and that's about it.
00:26:31.280 However, there’s one thing to note: whenever you have a belongs to association that you want to invalidate, you need to add touch: true on it, so the updated at changes.
00:26:43.760 To conclude my knowledge on Rails caching, just go with it! Being everything already in the browser means you can easily filter stuff client-side, right?
00:26:58.760 So she could have the search she wanted, and it would actually be faster. This led to yet another simple stimulus controller.
00:27:13.520 On every keystroke, it just stores the query in a variable, and every time it changes, it filters and hides items.
00:27:30.360 Ultimately, I’m happy with where this landed. You can scroll through everything, type in search words, and checkboxes for different movement patterns.
00:27:44.160 One of my favorite features is that if my frontend code or what I'm talking about interests you, you can view source maps in production, allowing you to read and play with all code interactively.
00:28:01.840 You just need to subscribe to the app for $30, which also includes a fitness app.
00:28:15.560 Learning when to say no helps me remain true to my vision, leading to better software through discipline. The empowered programmer is finally meticulous.
00:28:30.880 Rails was created by people who sweat the small stuff, so it’s no surprise it gives you what you need to pay attention to those details.
00:28:44.000 Admittedly, I prefer real native apps with buttons over web apps pretending to be apps, and these fancy gradients don’t make this a real button.
00:28:57.760 I appreciate the little touches that go into software. For example, when making a site a progressive web app, it can own the full screen if someone adds it to the home screen.
00:29:09.760 I was happy to see David merge this, where now PWAs are turned on by default with any new Rails project, but you can do what I did and copy-paste from the GitHub UI into your project to add them.
00:29:25.840 Let’s demo the workout UI. Each set looks like a little card with an instructional video.
00:29:39.840 Users can scroll down to see their past notes for a movement, with controls to complete or skip a set. Many of those tiles are interactive, allowing navigation between blocks.
00:29:53.040 Users can expand or contract videos and see timers—things like that. There’s a lot of fun! When I demo this, people often ask, 'Wow, how did you do that?'
00:30:05.360 Fortunately, most of you are seated because the answer is an 8 kilobyte opening div tag, numerous stimulus controllers, and a whole bunch of data attributes storing the entire UI application state.
00:30:16.160 I’m so productive with Stimulus because instead of managing separate server-side and client-side state, the DOM sits in the middle as the true source of record for everything.
00:30:29.520 First, Rails renders the page. Suppose a user clicks the complete button—this triggers a stimulus action that updates the data attributes, generating a fire-and-forget message.
00:30:43.440 This message updates the data on the server, animates the next set, and updates the current URL. So if you hit refresh, you're in the right place, not jumping around.
00:30:58.720 I know it’s a lot; it was for me too. My generalized advice is: when you're using Stimulus, just do whatever the server would do without JavaScript and keep them aligned.
00:31:11.440 When the user takes action, update the UI optimistically, and persist whatever you need to do via a fire-and-forget message that doesn’t block the user.
00:31:25.120 Finally, ensure at every step that you’re passing the refresh button test.
00:31:29.920 Refresh the page, and you’re not jumping around. A good Stimulus controller is like a good babysitter; it makes the same decisions a parent would.
00:31:38.080 Now, let’s demo a situation that often occurs in gyms where people juggle multiple devices, ensuring they don't perform unnecessary activities.
00:31:46.080 Here's an iPhone and an iPad. Watch the progress bar on the iPad as the user completes sets on the iPhone. You can see it fills in automatically, updating the exercises reflected in all clients simultaneously.
00:32:07.920 If you open that more tab and start typing a note, 'I’m having such a great workout,' as soon as you blur it, it’s also going to appear on every single device.
00:32:21.280 What is this dark magic, you may ask? It starts by attaching to Turbo Action cable using the turbo stream from a helper and in an after-commit hook in the model.
00:32:34.720 Using broadcast render to point out a partial, the turbo stream action is rendered with a tag. Turbo Stream makes monitoring changes to the DOM easy.
00:32:47.760 This stuff is all super cool, but if you’re like me, you might find something that worked once and then forget how to implement it later.
00:33:01.120 When that happened to me in 2006 with Rails, having recipes was helpful as a step-by-step guide. It’s been a while since we’ve had to adopt such a mindset shift.
00:33:15.120 I wrote this little recipe to guide you through implementing similar features in your own apps.
00:33:28.960 Hotwire generally recaptures a lot of the magic of Rails 1.0 while retaining the misery of unlearning previous methods.
00:33:41.840 I continue to be amazed at how Rails makes obvious things easy without making super obscure and detailed things hard, which I, as a meticulous person, truly appreciate.
00:34:04.080 Next time you start working on a new project, ask yourself which of these six traits might benefit from a bit of strength training, and what new features in Rails might help.
00:34:18.640 If you're interested in Build with Becky, you can learn more and sign up at betterwithbecky.com.
00:34:31.200 I won’t claim to be skeptical, but I’ve been weightlifting for a few years and did last month's program from Becky to test the app. I broke eight personal records, so I was pleased to discover it works!
00:34:45.280 Thank you for your time! I’m staring at the end and not planning to make a pun like 'Now that's a load test!' Thanks for the groans.
00:34:56.560 But even if it’s not your cup of tea, maybe you know someone who would be interested. Please tell them about it.
00:35:07.040 We haven’t announced it yet, but we only have about a dozen subscribers so far, and I’m sure Becky would be thrilled to have all of you and your friends on board.
00:35:20.640 Test Double is also here at the conference sponsoring. We've got kind of an office hours awkward space where you can pair program or get some free consulting at the Double Up Lab.
00:35:35.600 The next session started about two minutes ago, so go check it out. I hope to see you there.
00:35:44.560 Thanks for coming to my last conference talk! I guess I'm done doing this, but I can't help but create content.
00:36:00.240 I do have one breaking change to share—just kidding, that's the name of my podcast!
00:36:16.960 As Mike says, if you're still here, there's a chance you don't recoil at the sound of my voice for three hours. If you’re like Nadia, you might subscribe to catch up with what I’m doing occasionally.
00:36:31.040 It’s a laid-back, low-stakes listen with explicit language. Last year, I also started a free monthly newsletter called 'Searls Of Wisdom.'
00:36:44.160 Like Eileen, I generally dislike newsletters, so I strive to make one that's actually good. If I can get Aon to check his email, then I know I’m doing something right!
00:36:56.560 Finally, if you want to get in touch anytime, please email me at [email protected]. I’d love to hear from you—fewer people are emailing than you might think.
00:37:10.240 Thank you so much for being here with me today!
Explore all talks recorded at Rails World 2024
+17