Charles Max Wood:
Hey, welcome back to another episode of the Ruby Rogues Podcast. This week, I'm your host, Charles Max Wood, and we are talking to Garrett Diamond. Did I say that right, Garrett?
Garrett Dimon:
You did. You nailed it. Like Simon.
Charles Max Wood:
All right, yeah, do you want to tell people who you are and why you're awesome?
Garrett Dimon:
Oh boy, uhhh... Where do I even start? I've been doing software, I guess, for about 20 years. I started out more front end information architecture, consulting, lots of enterprise exposure for better or worse, a little of both probably. And eventually stumbled into Ruby and Rails after just really not enjoying the.NET world. And just totally fell for Ruby and really, really enjoyed it. Everything I didn't like about C sharp and.net Ruby just made it so I didn't even have to think about it. And went all in on that. Um, I built a small SaaS app, a bug initiative tracker that I ran as a sole founder for eight years. So I was doing marketing support, design development, front end, back end.
Charles Max Wood:
Oh wow.
Garrett Dimon:
Database,
Charles Max Wood:
Which one was that?
Garrett Dimon:
uh, sifter.
Charles Max Wood:
I don't think I heard of that one.
Garrett Dimon:
It was smaller. And then in, oh, I don't know. What was it, about six or so years into that, I had a surgery that the recovery went sideways, ultimately ended up leading to left below knee amputation. And then kind of anticipating all of that, I decided to sell the business and kind of focus on recovery and health and all of that. I joined my friends at Postmark. to help them with kind of a hybrid marketing, dev, evangelism role. And did that for almost four years until realizing I really missed writing Ruby day-to-day and then kind of went back out, went independent for a couple of years. And briefly joined up with the Egghead team as they were kind of transitioning to skill recordings, but actually just got laid off from there a little while, I don't know. a couple months ago and have been back in kind of the independent consulting world, most likely
Charles Max Wood:
Gotcha.
Garrett Dimon:
working with the Flipper team on feature flags stuff and Flipper Cloud and helping them kind of get that going. And then just stumbled into sharing some of my experiences with Rails generators and how I've found them to be just wildly powerful. And I feel like one of the... underutilized features of Rails and started getting more into that and sharing ways to leverage that, save time, and just kind of be more efficient and take advantage of those instead of just letting them hide away in the corners.
Charles Max Wood:
Yep. Very cool. Yeah. That's quite the, uh, resume you got there. And yeah, definitely have connections at some of those. Uh, John Lindquist actually lives not too far from here. And
Garrett Dimon:
Yep. Was
Charles Max Wood:
yeah.
Garrett Dimon:
at his house, I guess, I don't know, probably about a year ago.
Charles Max Wood:
Yep. Yeah, out here. He lives in the same city I live in. So
Garrett Dimon:
Oh, right on, right on. Okay, so I
Charles Max Wood:
yeah.
Garrett Dimon:
was right around the corner from you.
Charles Max Wood:
Yep. Right. In the same part of town. So in fact, I see him at the church building sometimes. So
Garrett Dimon:
Nice.
Charles Max Wood:
anyway,
Garrett Dimon:
Small
Charles Max Wood:
good
Garrett Dimon:
world.
Charles Max Wood:
deal. But yeah, it is. I love doing this though and getting to know new people. So yeah, it's awesome. And we're not that far apart either. You know, you're over in Colorado and I'm here in Utah.
Garrett Dimon:
Right, right? Virtually neighbors.
Charles Max Wood:
But yeah, something like that. But yeah, let's dive in and talk about generators. Now I'll admit I have thought about writing generators, but I have not actually done it. Just because essentially, occasionally I'm like, oh, I'd like this to come in. So just to give an example, and then we can kind of dive in and you can tell me how you would do this. I, a couple of years ago, I was working for Morgan Stanley and my boss had come up with this method for essentially connecting stimulus controllers with view components in Rails. And it's not really that far outside the realm of what you would normally do anyway. They tell you how to do it on the view components website. but we would always generate the view component and then add the JavaScript file. And I always thought, you know, it'd be really nice to just have my own generator so that I didn't always have to tell it, do the sidecar thing and then, you know, add the JavaScript file and just kind of move things in that way. And then the other thing is, is yeah, occasionally I have to pull some other piece of something in that doesn't really fit the rails generators that are in there. And so it's like, oh yeah, I'm doing this over and over and over again. It'd be nice to have it generate that stuff. So I'm really interested in this and really interested in what we can do with it. Um, besides the two examples that I have though, I'm curious, have you seen people using custom generators in other ways?
Garrett Dimon:
Yeah, there's, I mean, it's one of those things where once you kind of absorb it, it's almost The bigger problem is when you have a hammer, everything looks like a nail. And then you started thinking,
Charles Max Wood:
hahahaha
Garrett Dimon:
Oh, I could use a generator for this. I could use a generator for this. So the bigger problem is almost exercising discipline and, you know,
Charles Max Wood:
Right.
Garrett Dimon:
using it judiciously because otherwise you could easily spend two weeks building a generator to save yourself five
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
minutes a week, and that's not going to pay
Charles Max Wood:
Right.
Garrett Dimon:
for itself anytime soon. Um, and so that's, that's kind of been more of the challenge and a lot of what. I am eventually hoping to focus on with like what I'm sharing and how I'm leveraging them to where it's really about gains, not just I know how to use them, so I'm going to use them. Um, and, and my story is probably not too different from yours where over the years, there were several instances where I would sit down and be like, this sounds perfect for a custom generator. And I'd start to try it out and work on it. Um, but because it's not. You know, it's interesting because they are a central feature of rails,
Charles Max Wood:
Yes.
Garrett Dimon:
at least the built-in generators are. Um, but at the same time, they aren't a, like they have in my head, they are the most central feature of rails that is not promoted, advertised, pushed. Um, but I mean, obviously like the original video and everything that got people excited about rails. was in large part because of the work
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
that the generators were doing. So there's, we all know there's power there. We all use them. We, you know, even if we don't use them religiously, we use them for models, migrations, you know, some of the basic stuff.
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
So that was kind of how it got started. The first few times I tried, I'd get a little bit into it and then I fail and just give up and I'd go write a shell script or Ruby script or what have you, break task. But once, um, you know, I don't even, oh, it's cause so my new site, I rebuilt my site and it is all built with just markdown files. And so I wanted a generator to generate my blog posts and markdown files for me.
Charles Max Wood:
That makes
Garrett Dimon:
And,
Charles Max Wood:
sense.
Garrett Dimon:
right. Um, and it does a lot more than that too, but I was like, okay, I'm, you know what? I'm going to figure this out. Like I've been doing this long enough and just decided I was going to figure it out. No matter how much. I went down the rabbit hole and it was not a good ROI in terms of time spent. And once I did, it all just kind of started clicking and I'd see how powerful they can be with very little code, at least in terms of code generation. And so I just kept uncovering things and uncovering things. And then once you... get past the speed bumps that aren't necessarily super well documented and that kind of thing, they just, they enable a lot of efficiencies. In particular,
Charles Max Wood:
Right.
Garrett Dimon:
when you really boil it down, a generator is almost codified documentation, right? So say you have a system that uses adapters, and even if you have a parent class that drives a lot of that, There's certain things you're going to redo each time you create a new adapter for a new service. And you can write all that down in a file and expect somebody to read it, or you can just codify it. And then they could just run a command and get started. Right. And none of us like the tedious copy paste, search, replace dance of like, let me go take my last adapter, copy that over to this, delete everything, run the test. Oh, I missed a spot. Now I got to go back and fix that. And then, okay, now I'm ready to go. We just want to run the generator and get to work. And the nice thing is too, and I haven't, in the questions you ask, the answer's always, maybe the standard programming answer, it depends. Because
Charles Max Wood:
Right.
Garrett Dimon:
there are several different ways you can handle, you can extend generators, you can call generators from within generators, right? So there's... There's different options to, you can change how they're, um, how they're configured. Right. So like when we say you start a project, use R spec instead of mini test. Now the generators are going to hook into R spec and they're going to generate specs instead of mini tests. Um, so there's all those kinds of things that they can do. And a lot of it gets advanced and some of it gets kind of intimidating and overwhelming because there are so many choices. And so. what I've been trying to do is just boil it down to like remove all of the really fancy parts. They exist, they're there, they're helpful. But to me, they made generators so much more intimidating. But once I just started realizing how the basic templating works, the inflections that are available, how to concisely and efficiently set up the arguments and the options, then It just became so quick to quick, you know, to make a really powerful generator with not much code. And it's also well tested on top of that because generators are. Important enough that they even have their own assertions and their own test cases. And so there's just so much there that I feel like we've underutilized. And so I just got excited about it and started sharing stuff and sharing stuff and then getting more excited about it. Cause I learned. more of the little nuances and all of that. So that went off on a very long tangent that didn't directly
Charles Max Wood:
Yeah,
Garrett Dimon:
answer
Charles Max Wood:
I have
Garrett Dimon:
your
Charles Max Wood:
a couple
Garrett Dimon:
question.
Charles Max Wood:
of questions there.
Garrett Dimon:
And so the other thing I will say, like adapters is a good example, right? Like generators and adapters. But then the question is, how often do you need a new adapter? Do you really is it worth it to have a generator for that? I think connecting things, I'll just say so like JavaScript and partials and or presenters that kind of thing or partials and models and migrations right so there's disparate things that are all loosely related but they're all going to need their own files and so that's kind of where to me it starts to like things scream at me this is a generator if there's multiple files and multiple file types involved then that's when you're talking to generator.
Charles Max Wood:
Right. Yeah, I read a book several years ago called Procrastinate on Purpose. And it talks a bit about some of the kind of automation stuff or training somebody else to do some of your stuff. Right. So because it talks about like automating and delegating and stuff like that. And his rule of thumb was basically if you do it like three to five times in a certain time period, I can't remember exactly what it was. Right.
Garrett Dimon:
Mm-hmm.
Charles Max Wood:
And it's a, you know, then you start looking at automating it. And that made a lot of sense to me, right? Because if you're at something you're gonna do on a routine basis, right? So it's basically the length of time and the number of times you're gonna do it, right? That's when
Garrett Dimon:
Absolutely.
Charles Max Wood:
it starts to be a productivity hack versus, you know,
Garrett Dimon:
And
Charles Max Wood:
yeah, I mean, I've,
Garrett Dimon:
I've
Charles Max Wood:
you
Garrett Dimon:
codified
Charles Max Wood:
mentioned it before, but I've.
Garrett Dimon:
similar concepts on a maybe painfully granular level that like when I try to describe it to people I've started to refer to as progressive automation. So like kind of like progressive enhancement with JavaScript right? You know you start with your HTML, you layer on CSS and JavaScript and it's still you know You can stop at any point and it actually works and it's done. And so to me, it's, I start out the first time and I just write it down as I'm doing it, like really short hand notes, like that would be useless to anybody else but me because I'm the person that did it. And then I'll repeat it a few times, um, and fill in some details and then I'll start uncovering edge cases because this time is different from that time. And before I know it, I've got a simple file text file. that has captured my experience performing that task five times. And so if I'm on a team, at that point, I might polish it up and share it with the team. And I say, hey, next time when y'all has to do this, see if this helps. And then, you know, I'm getting different perspective by end and I just gradually let things yell at me and pull me along. And so then once that happens, it might be like, okay, well now let's actually create a shell script or let's create some mini objects in the system so you can use the console and run this task real really easily with some validations what have you and then eventually those things can then be the building blocks for a you know a customer service interface or even a customer
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
self-service interface and it just progressively gets more but you don't just the first time you know that you could automate it but it's not worth it to automate it until it is worth it to automate it and so I kind of forced that process to drag me along, kicking and screaming. To where I'm like, I can't not automate this at this point.
Charles Max Wood:
Right. So... Yeah, I wanna back up a couple of steps
Garrett Dimon:
Yeah.
Charles Max Wood:
because there are a couple of things that I was wondering about. One is, as you said, so your blog, it's written in Markdown files and you were looking at using a generator for that. So is that in a Rails app then? Because we're talking about a Rails feature here.
Garrett Dimon:
It is an intentionally, absurdly overbuilt personal blogging tool because I've been writing on and off for 15 plus years and I know where I've had friction points and tried a bunch of CMSs. And I kinda just did it as like a hobby project. Like it's nothing that I can imagine ever dumping on to anybody else. Um, but it uses it basically it's marked down in a hybrid of ERB. Um, so that I can have little ERB helpers to generate figures, block quotes, pull quotes, um, code samples, et cetera. And it will generate semantic markdown consistently without me having to edit it because previously I was doing all that markdown or I'm sorry, mark up by hand. And if I needed to make a change that would need to be made across all of the instances, either to enhance it or to improve accessibility or whatever, it was a nightmare. And so now with the ERB helpers and it actually is view component as well. It makes it trivial. So I just type a little bit and then you add in like templates from RubyMine and it just makes it trivial for me to. Well, plus the generator does a lot of that for me, too. If it's images, I have
Charles Max Wood:
Nice.
Garrett Dimon:
an images directory. It'll grab all the images. It'll read through them. It'll automatically insert all the ERB for me ahead of time so I can just sit down and write and not be bothered with flipping back and forth between the file system and the post and all that stuff.
Charles Max Wood:
Yep. So, you know, going back to the original question, so is it running in Rails then?
Garrett Dimon:
Yes, yes, everything's totally all in rails. And like I said, it's kind
Charles Max Wood:
Okay,
Garrett Dimon:
of overbuilt
Charles Max Wood:
you just have
Garrett Dimon:
intention.
Charles Max Wood:
a different engine for
Garrett Dimon:
Sorry.
Charles Max Wood:
those
Garrett Dimon:
Uh, yeah, I meant
Charles Max Wood:
templates.
Garrett Dimon:
to imply that when I said overbuilt, um, to go use rails, to build my custom CMS. Um, but a lot of that too, it's just, like I said, I love using Ruby. I love using rails. And so to me, and I really actively tried to avoid building my own system. I tried a bunch of things for a while and did a lot of research
Charles Max Wood:
I feel
Garrett Dimon:
and I was
Charles Max Wood:
you
Garrett Dimon:
like,
Charles Max Wood:
so much right there.
Garrett Dimon:
like I shouldn't do this, I know I shouldn't do this, I'm gonna try to avoid doing this. And it's, you know, like I said, I make the things drag me along kicking and screaming. And then I'm like, you know what, I should do this. And honestly, it was kind of a leap of faith based on like I said, 15 years of writing and knowing what I liked and didn't like and what
Charles Max Wood:
Yeah.
Garrett Dimon:
I wanted to publish and how I wanted to publish it like the richer posts like the
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
rails generator, like 101 type post. I never would have written that because it would have been too much of a pain for me to format all of that and present it and make it responsive and then fix bugs. And it just wouldn't have ever gotten written. And that's the type of thing I wanted to write more of. And no tool I found made it so that I could execute that in the way I wanted to. And so it feels kind of silly, but now I've written more. in the last couple months since I launched it than I had in the previous probably six years.
Charles Max Wood:
Nice.
Garrett Dimon:
So I think it's working so far.
Charles Max Wood:
Yep. So the other question that I kind of wanted to get into, and you know, yeah, we've already been talking for 20 minutes, is so let's say that I have this generator that I want to build, right?
Garrett Dimon:
Mm-hmm.
Charles Max Wood:
You know, and you talked about over engineering your own solution for stuff and, you know, don't build it on your own. And yeah, you know, top end devs is a podcasting. web course website that I built in Rails, right? Because
Garrett Dimon:
Mm-hmm.
Charles Max Wood:
I couldn't find anything that kind of, it felt like it was more work to figure out how to plug all the different pieces together and make them look like they belong together than it did to just custom build my own thing. But what I'm finding is, is yeah, there are certain things that I wind up doing on a regular basis that it would be nice to have a generator for, right? You know, some of
Garrett Dimon:
Absolutely.
Charles Max Wood:
it's down to like permissions, right? On stuff. and just managing that stuff or, you know, there are a number of other things. So if I wanna build a generator, what do I do?
Garrett Dimon:
So I'm going to give you a tangential answer first. And this is just to reinforce
Charles Max Wood:
I'm getting used to those, that's fine.
Garrett Dimon:
that productivity thing. You don't. You really think about it ahead of time because in a lot of what I'm trying to do, And I promise I'm going to get back and answer. We'll just take this real brief tangent. Generators are what they are. They are capable of what they are capable of. The time to build a generator is kind of the variable, like how long it takes you to start a generator and finish it and have it working. A task, say a given task takes you 30 seconds. And if you perform that task once a week, then your ROI, meaning like the value you like, I could maybe spend 10 minutes on a generator and this will pay for itself and 20 weeks. Okay, so you can't really change that 30 second task directly. And so that's a fixed budget. If you think about it that way. So my goal is to think about how do we make it so that the creation of the generators is so little time that even small tasks that are tedious could be responsibly. handled by a generator so that you're not
Charles Max Wood:
Right.
Garrett Dimon:
over investing. So that said, the nice thing is Rails has a built-in generator and it is
Charles Max Wood:
hahahaha
Garrett Dimon:
the most tedious part of the book that I've started writing and I will almost regret it is I'm building the example as a custom generator generator. that goes beyond what Rails gives you.
Charles Max Wood:
Okay.
Garrett Dimon:
And so I'm building a generator that generates a generator, but I use the Rails custom generator or the Rails built-in generator to generate the initial generator. You can see how it gets very circular and,
Charles Max Wood:
Hahaha, right.
Garrett Dimon:
I'm working on ways around all that stuff. But, so the nice thing is there's the built-in generator. It's pretty bare bones, pretty simple. It gives you mostly the files and the directory structure for your generator. but it doesn't really
Charles Max Wood:
Right.
Garrett Dimon:
do much beyond that. And that's fine. I still use it. And the only real, or kind of that first initial speed bump is that Rails doesn't explicitly document the parent class in a way that, at least not in the guides and not very much in the API. that makes it clear that you kind of have two potential parent classes to inherit from to start your generator. And the default parent class is Rails Generators named base. And that inherits from Rails Generators base, but named base includes a name argument, right? So that very first value when you type rails, rails g model, and then the model name. That's your name. And that's there by default with named base. And so if you don't know that and don't expect it, and previously the guides didn't really address it, they've been improved a little bit. And I'm actually planning some time in the near future to circle back and apply some of what I've learned to fill in some of the API docs as well. But that can be a speed bump in and of itself. And then there's a handful of other little. undocumented quirks where unless you go dig into the source code or you really try doing a bunch of variations you're going to hit those speed bumps. But otherwise you generate that generator, you have a skeleton, it's a Ruby file, and any public methods you write it will run in the order they're declared. And you'd want to think through what arguments and options you need, what information do I need to give my generator so it can do the job it needs to do. And arguments and options support a handful of types, so they conveniently handle some of the typecasting and type checking to take a command line string value and get it into an integer, a float, an array, a hash, a boolean,
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
what have you. And then you set up your arguments. which are your primary values, right? So like in the case of like the model generator, the name and the attributes are your primary arguments. They don't need a keyword. You just use the name and then you list out the arguments, the types and all of that, the index information if you want. And then the options are the things where you can kind of, those are the flags, standard dash word or dash letter. Declare those. Those will get sucked in. You can access those. The arguments you can access directly by their name, which can lead to some conflicts if there's existing methods or inherited methods and attributes, that type of thing. The options you access in an options hash. So you can get to all of these values from either by calling them directly or calling options. option key. And then within all of those methods, and I usually try to keep them really small, like I'll create a lot of methods that are very short and just name them very explicitly. So it's like create this file, copy this file, build this file. And the primary command there is template, and it looks in the And that's ERB. And then you have, you know, assuming you're using named base, you have a name and thus you get access to a whole plethora of inflections for the class names, the file names, there's even a fixture file name inflection. And so you don't even have to then once you do have to learn them just like anything else. But once you do learn them, like none of us go, how do I update an active record instance? What's that method called? Right. Like we don't do that anymore. We just know. It becomes second nature. And so you learn, okay, template, source file, destination file, done. Or even better yet, there's a directory command that will recursively do a directory and all of the Thor template files in that directory. So one command can recreate a whole directory. And I haven't
Charles Max Wood:
Oh nice.
Garrett Dimon:
ever looked, I should look at the view component generator because I know it does a lot of heavy lifting. but I have
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
not circled back to look at it. But I wouldn't be shocked if it, well, maybe, I don't know, that's a whole other rabbit hole. But so then you have all of these,
Charles Max Wood:
Hahaha, always.
Garrett Dimon:
you have all of these actions, template, and some of them provided from Thor, and some are rail specific, right? So you can insert
Charles Max Wood:
Okay.
Garrett Dimon:
gems into the gem file. So there's, I've kind of classified everything as, there's things that create files, There's things that modify files. And then there's a whole grab bag of other handy things. Like you can run git commands via Ruby in the generator.
Charles Max Wood:
Right, okay.
Garrett Dimon:
You can run system level commands. You can run other generators with the generate command. So you would just say generate and then the generator name and then the parameters.
Charles Max Wood:
I think some of the built-in ones do that.
Garrett Dimon:
Yes. And so there's
Charles Max Wood:
Right.
Garrett Dimon:
a lot
Charles Max Wood:
Because
Garrett Dimon:
of different
Charles Max Wood:
they generate
Garrett Dimon:
ways you
Charles Max Wood:
a view
Garrett Dimon:
can.
Charles Max Wood:
and a test and all that stuff. Yeah.
Garrett Dimon:
And then they have hooks that hook into the other generators and call them. Um, and so that stuff can definitely, um, it creates a lot more noise and distraction because those aren't necessarily features that the average person needs to use to automate a tedious task. And so that gets back to where my goal is to help people not get bogged down in all that generators can do. but to understand that 20% of their primary power that gives you 80% of the results so that you can very quickly build a generator. And so now you don't have to be facing a task that takes you 30 minutes every time and you do once a day, it starts to become economical for tasks that are one minute or two minute tasks that you may be performed three or four times a week. And mind you, that's all just the building portion. Like I said, they have their own custom assertions. and test cases, which make it very, very nice to test them, not even because of the assertions themselves, but because of the fact that as rails does, and just like with database transactions, after every test, it's clean, you have a clean working directory, you don't have to worry about like if you write a shell script or Ruby script, it's doing file manipulation stuff
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
and creating
Charles Max Wood:
Right.
Garrett Dimon:
A, you could accidentally copy it to the wrong place because you used an absolute path or relative path in the wrong spot.
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
And now you've got this junky file somewhere in your system. You don't even know where it went. And especially if you're manipulating the text of files. And so you run it once and then you go, okay, did it do it? It did do it. I needed to do. Okay. It did. Now I need to go clean up all that cruft and start over and rerun it. And that gets to be a very manual tedious process.
Charles Max Wood:
Right.
Garrett Dimon:
And with automated tests and rails. and generators, it just does that cleanup for you.
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
And if you get outside of what that cleanup does, it's not difficult to use the other existing things or even use file utils or what have you to build a little bit of extra stuff to help you with that cleanup. So to me, there's just so much power in all of those things. And it's so just kind of the, I mean, a lot of the conventions come from Thor. So it's weird to refer to it as Rails conventions because in this case, it's stuff that's defined in Thor, but like the fact that just, it's just gonna call every public method you list. And then every
Charles Max Wood:
Hahaha.
Garrett Dimon:
one of those public methods just uses some actions like template, copy file, create file. And then there's all of the other like rail specific utilities for the things we know and love, like manipulating our gem file, all that stuff, it's there. It's just handy once you see it and you're like, it just clicks and all of this low level file, you tell stuff is just handled for you with a single method call and two arguments like. It's tough to beat.
Charles Max Wood:
That's awesome. So I'm wondering then, shouldn't you just talk about some of the benefit here? Cause you know, everything you're talking about, you know, it just makes sense to me at
Garrett Dimon:
Mm-hmm.
Charles Max Wood:
least, cause I've just, I've seen gem or I've seen generators do pretty much everything you're talking about, right?
Garrett Dimon:
Right.
Charles Max Wood:
So I'm curious to know then, and you've talked a little bit about like with your blog and stuff, using these generators to create the, you know, the blog post template and things like that. I guess the next thing that I'm kind of thinking about is like where else have you seen generators used in kind of an interesting way or where have you used it yourself? That's really paid off.
Garrett Dimon:
Yeah, I mean, so for the most part, I would say I haven't seen generators used enough in interesting ways. The, I would say the most common scenario where I see generators used is in gems, right? People want to provide you a more streamlined. set up experience or things like view component, right? Where they need a generator because it's basically a partial. And so you've got a partial generator, why not have the view component generator? And so it's mostly been those. And what I feel like the biggest opportunity is, and like that makes sense. And those get a little more complicated because of the gym, you have to handle more variations of people's Rails application. But what I've... gotten more excited about is enabling people to do things. I mean, I'll use the service object pattern as an example. I've started personally shying away from that more and more and more, but service objects or command objects or query objects, those are things that once you start using those and your team is comfortable with those patterns, then you... You kind of have a choice. You're like, okay, well, there's a lot of stuff we can do with just apparent class and inheritance or with composition, what have you. There's plenty that you can do that way. And generally that's what you want to reach for first, but there are going to be cases. Um, and I think too, the one that I get excited about is like, even if it's just a simple service object, but I know the service object would have you know, okay, it's going to have results. A lot of that's going to come from the parent class, but it can also have kind of a skeleton pre-built for your tests so
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
that when you write your object, you also already have a placeholder to write the corresponding test to verify the results of it and that sort of thing, or a query object, the same kind of thing. You get into these patterns that are predictable and nice so that the whole team knows when I see a query object in this app, it's going to behave this way. And so you can have a generator generate the query object and generate the test file. And now you just get to work, right? So you're not switching to finder your file system to copy a file or. Any of that kind of stuff. You run a command that builds it and your placeholders are in place and you just start typing the stuff that matters. So you don't even have to think about it. So a lot of it is that kind of just removing friction so that you can get to the part, the high value work. Because. Copying and renaming files on the file system is not high value work for any of us. And that's the way most of us just kind of default to doing it. And that's just, that's all focused on if you don't get sidetracked when you're switching contacts and bouncing between apps and you get sidetracked and get off on a different tangent, then that costs you even more than the 30 seconds or whatever it would cost to do the file manipulation. Um, so to me. that's where the value starts to come in, is these kind of almost overly basic opportunities, so that now when a new hire comes in and they need to build a service object or a query object or whatever it is, they don't have to read a document, whole set of documentation to understand, here's how we do things. Run the generator, and the generator already has the documentation, and like do this first, do this, fill in this, fill in this, make sure it returns this format. And you're done. And by the way, your test, you know, here's the exact matching spot for the test to fill in and verify the results. And that to me is where it starts to be like there's almost just ridiculously simple use cases start to become. Economical.
Charles Max Wood:
Yep. Yeah, it makes sense. One other thing that I'm kind of wondering about, and I don't know if it. Did this through Rails application templates or if they use generators or both. But I remember way back in the day, in fact, I just looked it up and it still has a. Reference for a video that I made about it, but it was called Rails Composer. So you would run Rails Composer and it would say, okay, do you want like Bootstrap or Zurb Foundation or any number of other different visual
Garrett Dimon:
Mm
Charles Max Wood:
setups,
Garrett Dimon:
hmm.
Charles Max Wood:
right? Do you wanna use OmniAuth or Devise,
Garrett Dimon:
Yeah.
Charles Max Wood:
which isn't really a binary choice anymore, stuff like that, but Pundit versus CanCan. Anyway. So what I'm wondering is... Yeah, you know, would you do some of that with generators or?
Garrett Dimon:
You absolutely can. If you think about the built-in generators, the Rails built-in generators seem to shy away from it. I can't
Charles Max Wood:
Yeah.
Garrett Dimon:
think of any that once you type the command and hit enter need anything from you Thor does provide Interact like methods for interaction
Charles Max Wood:
Mm-hmm. Okay.
Garrett Dimon:
They're not super fancy like multiple choice
Charles Max Wood:
Right.
Garrett Dimon:
arrow up and down all that but
Charles Max Wood:
Yeah.
Garrett Dimon:
it provides ask and then Yes, and no to where you know you use the command it prompts out They respond and then depending on the answer, you can branch and do a little different stuff.
Charles Max Wood:
Okay.
Garrett Dimon:
And so naturally you could ultimately, and I haven't because I try to, again, for me, so much of it is the simpler the generator is and the faster it is to generate
Charles Max Wood:
Right.
Garrett Dimon:
the more opportunities I'm bailing myself out of tedious work that I hate doing. Um, and so I generally don't reach for any other libraries, but that stuff is built in. It's right there, you know, at hand and can do some of that. But I also think. as soon as you start creating a ton of branching and all of that within a generator, it's going to get tough. And so, and that's why I think Rails has so much of the built-in stuff where you specify in your configuration, we're using RSpec, not Minitest. And that way, you don't have to tell the generator every time you run it, hey, I'm using RSpec. Because that, it's just one more bit of friction and steps that now you've got to answer questions every time. And I think there's, I'm sure there's use cases for it that would be helpful. But in my experience, you want to like, not make people make decisions any more than they have to. Um, but it exists and it's there. I haven't seen it used anywhere, any of the rail generators that I've noticed. Um, but it's, it's certainly available.
Charles Max Wood:
Cool. Yeah, I'm really just, I kind of want to just dig in now and just be like.
Garrett Dimon:
That's what happened
Charles Max Wood:
But
Garrett Dimon:
to me.
Charles Max Wood:
the
Garrett Dimon:
Like
Charles Max Wood:
thing
Garrett Dimon:
I started,
Charles Max Wood:
is, is I'm also. Yeah.
Garrett Dimon:
yeah, sorry. That's exactly what happened. I just, I was like, you know, I'm going to force myself to do this. And then the more I learn, the easier it becomes and the more useful it is. And it just kind of feeds off of itself. Now my net investment right now is way negative because I've gone so far down the rabbit hole, um, to help like. hopefully proliferate some awareness and like reach other people and help them see the potential. But ignoring that, yeah, it's just like, oh, there's that. And that's like a candy store. It feels like once you really get in there and just start, you're like, this is so easy. Why did I wait so long?
Charles Max Wood:
So one last thing that I'm gonna ask is, it seems like, and I think I've seen different approaches to this more recently, is Rails engines versus Rails generators, right? And so
Garrett Dimon:
Mm-hmm.
Charles Max Wood:
I saw, I think it was an authentication option that was a generator instead of device, which is an engine. And so, I mean, it has a generator in it, right? But... The idea being that, hey, we're going to just stick the authentication logic into your application and then you can modify it however you need as opposed to having to interact with the engine and being somewhat limited in, hey, whatever I overwrite on the engine, I have to maintain. Right? And so now I'm maintaining against somebody else's code instead of code that's checked into my app. And I'm kind of curious, right? The same thing with like a blog or podcast, right? Rails Generate Podcast, and it gives you the controllers and the, right.
Garrett Dimon:
Mm-hmm. Yep. completely boiled down answer would be that generators are really, really good at small. bits of code.
Charles Max Wood:
Okay.
Garrett Dimon:
Where small is relative. It absolutely could work for what you're talking about, but I think the biggest catch you're gonna run into is that, is future updates, because it's basically acknowledging out of the gate, future updates are out of the question, because you're gonna be going
Charles Max Wood:
Hmm.
Garrett Dimon:
so far off on your own. And so in that case, the maybe the answer would be more of a hybrid solution where the core
Charles Max Wood:
Right,
Garrett Dimon:
internals,
Charles Max Wood:
which is kind of what device does.
Garrett Dimon:
the core, yes,
Charles Max Wood:
Yeah.
Garrett Dimon:
right. So that's probably a great example because they give you, you know, you have your views and whatever the core internals that's inherited. It comes in from elsewhere. It can be updated. And then you can just go to town on whichever, wherever you want to draw that line,
Charles Max Wood:
Right.
Garrett Dimon:
you know, whether that's.
Charles Max Wood:
So you could bridge the gap a little bit. Like, so if it was rails generate podcast, just as an example,
Garrett Dimon:
Mm-hmm.
Charles Max Wood:
not that that's anything I'm even going to do, right? Because I'm using CRUD and I'm putting it in the database, but,
Garrett Dimon:
Right, right.
Charles Max Wood:
you know, just to put it out there, yeah. So then it could generate the models and the logic and the view logic and stuff like that. And so then, you know, maybe I do have a podcasts controller. that it generates instead of having in the engine. But then I have a library that's effectively build RSS feed or something like that. And so if there are updates to the specification for podcasting 2.0 or iTunes or Spotify or something else, then build RSS feed, you just update the gem and that part gets updated because you don't wanna fuss with it, but you can mess with the controller to make it private. this or that or whatever.
Garrett Dimon:
Yeah, I mean, if you were spinning up, I think a lot of scenarios that make it where I haven't personally been in a long time and needed to, is if you're doing consulting and you're doing the same stuff for every client, then
Charles Max Wood:
Oh, I could see that. Yeah.
Garrett Dimon:
there start to be more opportunities to do things like that. I mean, there's also app-based, right? So you can generate, you can have Rails templates and generate Rails apps that are pre-configured to your specific proclivities. And... So there's always that too, but then with generators, you can do it again. Like my biggest problem is I keep coming up with ideas and like, oh, I could build a gem that adds on a little bit of extra functionality for specific scenarios
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
with generators for like image manipulation. So like with my blog posts and I write, I dump some images in a folder, I need to, they end up on Cloudinary and all that, but like I need to optimize the size. I need to do this and that, or maybe I need to open graph images or, you can have it do that stuff. Haven't decided if I want to go that far, but these ideas, like the potential of what it could do just every time I sit down just proliferates far beyond. The bandwidth I have to execute these ideas. And so it's mostly like, all right, well, what's really going to be valuable to help people bridge the gap from? I know they exist, but they're just. I've had a hard time using them to, oh, this is easy. No problem. I got that.
Charles Max Wood:
Cool. All right, well let's go ahead and do kind of the wrap up stuff
Garrett Dimon:
Yeah.
Charles Max Wood:
with PIX. Before we do that, if people want to learn more, contact you. How do they do that?
Garrett Dimon:
I mean, probably the easiest place, the most central is just garretdiamond.com, which I guess in hindsight needs spelling when you say it out loud. It's Garrett
Charles Max Wood:
Ha ha
Garrett Dimon:
with two
Charles Max Wood:
ha.
Garrett Dimon:
R's and two T's and then D-I-M-O-N. Although I think if you go Google or do any of the search engines for any mishmash combination of my name. shouldn't be too difficult to find. And then that links out to everything. And I think I'm Garrett Diamond on most things if I have a presence on it. So I'm around, but yeah, my site is definitely the linchpin at this point.
Charles Max Wood:
Cool. All right, well, we're gonna go ahead and do some picks then. Now, I never know if people know what picks are, so I'm just gonna let you know, it's kind of whatever you're into, right? So it could be technical, it could be non-technical. I always do a board game pick or a card game pick as is the case today. This is a game I'm pretty sure I've picked on the show before, but it's been quite a while. And we were just hanging out at my... Sister-in-law's house on the 4th of July, you know, lighting fireworks and, you know, eating food and all that good stuff. And we played a game called The Crew, and it's a card game. And basically you have cards, is it one through nine? I can't remember. I think it's one through nine, or two through nine. And then you've got a Trump suit, which is black, which is one through four. And so then what you do is you, you know, you just, it's a, it's a regular trick taking game, but the difference is you have little tiles that go on. So there are two decks of cards and the other deck of cards you shuffle and then you pull however many cards off the top. You put the tiles on it according to whatever stage you're on, right? So different stages tell you to do different things. Some of them don't use the card. Some of them is like every Trump card has to take a trick or, um, you know, you have to do. you know, none of the nines, which are the highest card, can take a trick, right? And so you've got to figure out how to finagle that. But, you know, and so you're working together as a team to try and get these to go. The tiles are usually, they have to be taken in this order, right? So it could be, this one has to be first, or this one has to be last, or this one has, you know, they have to be taken, you know, first, second, third, fourth, or, you know, these three cards have to be taken in order, but the last card can go anywhere in the order. And so the different tiles tell you different things. And then, you know, it's just a round of cards. Everybody has nine or 10 cards. And you know, you just play out the hand. And so it's pretty fun. Sometimes it gets a little bit tricky because you know, you wind up with a card in front of you that says, cause you hand out the cards to the different people. And so if you wind up having to take a card that's hard for you to get, right, you don't have the right cards that are high enough to write. And so there's a communication mechanism that you can, you know, this is my only green card or this is my highest or lowest green card. And so then you're playing the communication game to try and let people know what they should or shouldn't do in order to get the cards. And sometimes they're, you know, the rule puts a restriction on that. You can't communicate or. You can only communicate these ways. And so anyway, it's really fun. I think there are like a hundred different levels, right? So you start at the beginning, and there's a story that goes along with it in the book, but I mean, we always just, okay, we're playing this one now, right? And so we don't read through the,
Garrett Dimon:
Right,
Charles Max Wood:
you
Garrett Dimon:
right.
Charles Max Wood:
fly into a cloud of dust and now you can't communicate, you know? We don't read any of that. We just, you know, you just can't communicate.
Garrett Dimon:
You just play. Yeah, yeah.
Charles Max Wood:
But yeah, way fun. And yeah, you hit the rounds pretty fast. I forgot to look it up on Board Game Geek to let y'all know. Just pull it up. The crew has a rating of 1.97. So casual game, not very complicated. Says the ideal group of people to play is four. But yeah, we were playing it with five people and it's fine. We did find that on certain scenarios, the five players was harder. But anyway, fun stuff. So I'm gonna
Garrett Dimon:
right
Charles Max Wood:
pick
Garrett Dimon:
on.
Charles Max Wood:
the crew. And then just a couple of other things that I'm wanting to shout out about. So, I've been talking to a bunch of people and I'm finding a whole bunch of people that want to start podcasts about programming. Now we do podcasts and then we put the podcasts on YouTube. I'm getting more into YouTube as well. But if you're interested in that, just go to topendevs.com slash podcasting. And basically I just want to get a feel for where people are at and what you're struggling with. how to get one started, but I am going to be putting together a podcasting bootcamp for programmers. So it'll go beyond sort of the how to podcast and we'll get into, hey, if you get a tricky code situation that you want to talk about, you know, how do you give people an idea of what's in the code without reading it, right? Because reading code on podcasts sucks, you know, and things like that. And so we'll talk through some of those things, how to invite people. where to find contact info, because it's different for programmers a lot of times than everybody else. You can find people's contact info the same way you find other people's, but we have other tools, right? You can get it off GitHub, for example. So... Yeah. And then just how to pick the right topics and the right guests and stuff like that. Right. Which is sometimes specific to your technology area. So yeah, we'll get into all that stuff. And then I've been podcasting about programming for 16 years and I've talked to all kinds of people in all kinds of communities. And so I'm also willing to help people get connected with the guests they want, you know, provided that I think it'll be a good experience for the guest. Since I'm training you, I'm pretty sure I can make sure that happens. So anyway, um, topendevs.com slash podcasting is the place to go and we'll get that put together as well. Um, and then, uh, one last pick, and this is something that I've kind of just recently. So I'm, I'm fairly politically involved here in Utah and, uh, our county parties website was having issues. And so, um, I contacted the guy that's hosting it. And he actually gave me access to cPanel. Now cPanel used to be this awful piece of garbage, right? But doing the things that I needed to do using it this last time, including adding an SSH key for the things that just weren't easy with it, was pretty actually not terrible. It was nice. So I'm going to pick cPanel. If you haven't used it for a while, it may be worth looking at. If you have non-technical or semi-technical people that Don't want to SSH into the thing, but give them access to be able to manage it like a WordPress website, which is what I was fussing with. WordPress is not my favorite thing. But anyway, so yeah, so I'm gonna pick cPanel as well. Garrett, what are your picks?
Garrett Dimon:
Oh man, well since you were doing games, I've got to say that we have been loving and simultaneously frustrated with Magic Maze, which is,
Charles Max Wood:
magic maze.
Garrett Dimon:
it's a collaborative game, but it's time-based and you can't, it's similar in terms of communication. The only way you can communicate is by passing a marker and you can put it in front of somebody. So everybody has a subset of things they can do, which is one person
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
can go up, one person can go down, one person can go right, one person can go left. And you've got to work the characters to a certain point and then back out. But it's all on a timer. and you could get to certain points and reset the timer. And then that lets you go and it's an insidiously
Charles Max Wood:
hahahaha
Garrett Dimon:
like fun but stressful game and it progresses. So you start out simple and then each you can add in little more details that make it more complicated and more challenging as you get better at doing
Charles Max Wood:
Okay.
Garrett Dimon:
it. But the kids love it. I have very mixed feelings in the moment I hate it. But then afterwards
Charles Max Wood:
hahahaha
Garrett Dimon:
I have positive feelings about the process of playing it. So that's been a really fun one. And I was actually introduced to that while I was in Utah with the Egghead crew and we were all playing it together
Charles Max Wood:
Oh nice.
Garrett Dimon:
as like a team thing. And so I think it could be a fun team game around the office too, for those of us that are in offices anymore. So yeah, so on the game front, I would definitely have to say that.
Charles Max Wood:
I'm just going to add a couple of things here. It says it's 8 plus. Board game weight is 1.77. So again, real easy casual game. It says that it takes 15 minutes to play. Does that sound right to you?
Garrett Dimon:
The rounds, yeah, probably about that. Pretty, pretty quick and easy. And then, you know, that way as you get more and more stretched out, you're like, I'm done, I can't do another round. That type of thing. So, cause it gets real
Charles Max Wood:
Yeah.
Garrett Dimon:
anxious and everybody's like, yeah, it's fun. The kids love it. Um, that's been great. Um.
Charles Max Wood:
Nice.
Garrett Dimon:
I'm trying to think if that was, just popped right into my head as you were talking about games.
Charles Max Wood:
Oh yeah, there's a ton of good stuff out there.
Garrett Dimon:
Oh yeah, absolutely. Trying to think if there's anything else that's just totally stood out for me lately as a super handy thing. All I've been doing is just writing, writing and writing and writing. Although, you know, I will say, I've given RubyMine a try on and off a bunch over the years. I've been a
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
hardcore sublime user just because of performance and simplicity and all of that. And so I kind of through just serendipity, multiple people mentioning it. It's, you know, heavy over, there's a lot of configuration,
Charles Max Wood:
Mm-hmm.
Garrett Dimon:
but as you know, kind of just getting into it more and more, it's been a pretty positive experience. You know, as long as you're willing to get over the learning curve, I've been really pleasantly surprised being somebody with a lot of interface design background too. that always turned me off on it. Like it just felt funky and they've recently done some refreshing and it's been a really solid tool that I've found myself turning to more and more and enjoying, not just tolerating, but like really appreciating some of the features and functionality in it. But it's a lot. a whole lot. Kind of overwhelming.
Charles Max Wood:
Cool. Yeah, I've used it off and on over the years. I haven't used it lately, but. Anyway, well, thanks for coming. This was a ton of fun. Definitely
Garrett Dimon:
Yeah,
Charles Max Wood:
got
Garrett Dimon:
likewise.
Charles Max Wood:
me thinking
Garrett Dimon:
Thanks for
Charles Max Wood:
about
Garrett Dimon:
having me.
Charles Max Wood:
where I can use generators. So yeah, we'll wrap it up here.
Garrett Dimon:
Yeah,
Charles Max Wood:
And until next
Garrett Dimon:
I'm
Charles Max Wood:
time,
Garrett Dimon:
going to keep cranking
Charles Max Wood:
oh,
Garrett Dimon:
stuff
Charles Max Wood:
good.
Garrett Dimon:
out about it.
Charles Max Wood:
Heck yeah. All right, folks, till next time, Max out.