50 minutes 29 seconds
🇬🇧 English
Speaker 1
00:00
Dear listener, if you're a Ruby on Rails developer or an aspiring Rails developer, I want to tell you about a resource I've created that I guarantee can help you become a better Rails developer, probably. I want to give you this resource for free. I'll tell you what it is and how to get it. But first, a little background.
Speaker 1
00:21
I've worked at a lot of jobs in the past where they had a certain class of problems. Their code was messy and hard to understand, which meant it took forever to make any changes. They couldn't refactor and clean up the code because it was just too risky to do so. There was no way to know you weren't breaking something.
Speaker 1
00:42
Deployments were also quite scary. We didn't have any automated tests, so each deployment had to be preceded with a round of manual testing, which wasn't always very thorough. Not to mention, manual testing meant that we couldn't deploy with any reasonable frequency, and therefore each deployment was huge, which made the problem even worse. And nobody wants to work at a place like that, so we had trouble attracting and retaining good people.
Speaker 1
01:13
It's no fun to work at a place from which all the smart people have fled. The problem at these places, or at least 1 of the main problems, was that they didn't have strong testing practices. I'm willing to bet, dear listener, that you've worked somewhere that has had those same kinds of problems. Maybe you even work some place like that right now.
Speaker 1
01:38
And you want it to get better, but maybe you don't know how to write tests. And maybe the people you work with don't know how either. Or maybe they do, but they don't have time to teach you. That's where I come in.
Speaker 1
01:51
I've created a guide called the Beginner's Guide to Rails Testing. You can find it at railstestingguide.com. I've been teaching Rails testing for years and so I've seen all the common Rails testing questions. Here are a few examples.
Speaker 1
02:10
Which test framework should I use? RSpec or Minitest? What level of test coverage should I shoot for? What are the different kinds of Rails tests?
Speaker 1
02:23
What are all the Rails testing tools and how do I use them? How do I add tests to an existing Rails project? The Beginner's Guide to Rails Testing covers these questions and several others. To get the Beginner's Guide to Rails Testing, go to railstestingguide.com.
Speaker 1
02:44
Now on of the episode. Hey, today I'm here with Joel Draper. Joel, welcome to the show.
Speaker 2
03:16
Hey, great to be here.
Speaker 1
03:17
Would you like to introduce yourself?
Speaker 2
03:21
Yeah, of course. So I'm Joe Draper. I am a Ruby programmer.
Speaker 2
03:27
I used to work at Shopify. And at the moment, I'm just working pretty much full-time on open source. I've recently been developing a new view component library called Flex, which you might have heard about. But it's kind of Similar to view component, but Instead of using ERB you can write all of your templates in pure Ruby
Speaker 1
03:55
Okay, I took a look at the flex website before we hopped on this call So I have a little bit of context. Oh, I haven't used Flex myself yet. I actually did a presentation on Vue component just a few days ago at this.
Speaker 1
04:12
It's a new thing I started. I call it the code with Jason meetup where we meet every Thursday night and I give a presentation and then we do some discussion Q&A type stuff. There's a different topic each time. Last time the topic was view component.
Speaker 1
04:27
Somebody asked me about Flex. They're like, How would you compare flex and view component? I'm like, well, I don't know because I've never used flex But I told that person that you and I were talking and I said I would ask you so it might be a natural first question is how would you compare Flex and ViewComponent? And why did you want to create Flex?
Speaker 1
04:52
Obviously, there must be something about ViewComponent that leaves something to be desired or something like that, or you just had a different approach you had in mind. So could you talk to us about that?
Speaker 2
05:04
Yeah, sure. So ViewComponent and Flex solve a very similar problem. ViewComponent gives you a object-oriented layer to your partials, where you have a class that represents a partial, essentially, a component of your user interface.
Speaker 2
05:29
And That is a nice layer of abstraction for defining things like methods that you can then expose to your templates. Flex is very similar, except instead of just being object-oriented at the kind of component and class level, it's object-oriented at the tag level, because every tag that you create is a method call. So If you want to have a component that has a template that renders an h1, you would define a method called template. And then you would call the method h1 and pass it any of your arguments or a block for the content.
Speaker 2
06:15
So it's very similar. But because of that slightly different approach, you get to, like, it's hard to explain, but you can kind of, like, For example, if you wanted to override the H1 method, which you could do, you can just define your own method, and you could say, like, all of my H1s in this class should have these attributes on them by default. So you can do that kind of thing. Or you could define, like, any part of that template to be a method and then just call it from the main template method.
Speaker 2
06:55
And kind of in the same way that you can break down a normal Ruby class, you can break down a view. Does that make sense?
Speaker 1
07:05
Maybe. I would be lying if I said I caught all of that. All right. I personally have a hard time understanding things without, like, seeing something.
Speaker 1
07:16
But I do want to make a comment before we go further. Talking about the problem that's solved by things like this, I have a little bit of a different view on it or a different way of looking at it. I'll share that and I'm curious to what degree it overlaps with the way that you look at it. When I first heard about View Component, I didn't understand what it was.
Speaker 1
07:47
I even had the view component creator on my podcast twice. And I think it wasn't until the second time that I understood it. I talked to him for a whole episode and didn't even understand what it was after talking with him for like 4 or 5 minutes. But then after I worked with it a bit, I finally understood it.
Speaker 1
08:09
It just had never been explained to me very clearly. So The way that I see it now is that among the different kinds of code you can have in a Rails app, 1 kind of code is view-related logic. Not just like a trivial conditional or loop or something like that, but actual meaty logic. Because if you put that right in the view, it's kind of weird because you're mixing concerns.
Speaker 1
08:40
You're maybe mixing levels of abstraction. But then if you put it in a helper or something, that can be unnatural too. Or if you stick it in a model, that's weird. Or the live.
Speaker 1
08:53
There's just no great place to put it. So ViewComponent, and this is not unique to ViewComponent, but ViewComponent can give you a place to put that view-related logic where it has a home of its own, where it's not intruding on anything else. Again, that's not the only way to achieve that. You could achieve something similar with the decorator pattern or something like that.
Speaker 1
09:18
But to me, that's the problem that that solves. So to what degree do you look at it the same way or see it differently or whatever?
Speaker 2
09:30
I see it pretty much exactly the same way as you do. I think that's a much better explanation than I've been able to come up with myself. So it's about having a Ruby object or a Ruby class that really models the piece, the component that you're talking about, right?
Speaker 2
09:53
And you're right, sometimes that can involve some meaty logic that's more than just like an if this, then that conditional. And, yeah, so it provides an abstraction for you to do that. And Flex is almost exactly the same in terms of how it models components. The main difference is Flex is essentially if you had view component, but you could define instead of an external template file in ERB, you could just make the template be 1 of the methods.
Speaker 2
10:33
So instead of having to have 2 files, and you have to remember 1 of them is the view, 1 of them is, like, the component that models that view, you can just have the 1 file, the 1 object, and it just responds to this special method called template.
Speaker 1
10:52
I see.
Speaker 2
10:54
And yeah, so it's very similar. But you get some advantages by building views this way. So for example, we in Flex, we always know exactly what you're doing at any point.
Speaker 2
11:09
So if you are, like, outputting some text in ERB, for example, I can't think of a good way to explain this. Okay. So let's say we wanted to we both want to achieve HTML safety. We don't want cross-site scripting attacks, which are where if you output user content, the user might be able to, like, construct some content that could break your site for other users and do things on their system by, like, running JavaScript without permission.
Speaker 2
11:48
So 1 of the things that could be used by an attacker for this would be encoding in a link href attribute. You can prefix that href attribute value with JavaScript colon and then any JavaScript. If you click the link, then that JavaScript gets executed on your web page. So ERB doesn't have a way to escape this, because they don't know when they're outputting user content, whether it's being output as the value of an href attribute on an a tag.
Speaker 2
12:28
Whereas in Flex, we know that that's the case. Other things like if you wanted to ensure that all of your IMG tags had alt attributes, like alt text, then you could do that just by defining an IMG method and ensuring that the alt keyword argument is provided. So it's like it gives you this extra layer of kind of introspection into the HTML that's being output. And it also guarantees that the HTML that's generated is always valid as well.
Speaker 2
13:07
Because you can't, for example, forget to close a tag.
Speaker 1
13:14
Does that
Speaker 2
13:14
make sense? **BEN HONGENBORG**
Speaker 1
13:15
Yeah. I didn't really understand what was compelling about Flex until just now. I think the IMG tag example was what illustrated it for me. Side note, Going back to before a little bit, I meant to include a certain example, which I think is a really compelling example of this idea of the view-related logic.
Speaker 1
13:44
I had a case in an application I worked on where I had a certain select input that was scattered throughout the application. And early on in the application's life, there were only a couple of these select inputs, and I could just do, it was a physician input, so I could just do physician.all, and that was fine. But then there grew to be more of these select inputs, and it wasn't just a list of all physicians, it was like maybe physician.active, because we had the idea of archived physicians after a time and then we wanted to order them in a certain way. And you Joel and probably you dear listener, you've probably had the experience of setting the options for a select input in a controller, and you either have to do it in both the new and edit actions, or you have to have a before action that calls this other method that executes before any of the actions and it's a little bit awkward and not only that like that's even if the select input only appears on 1 form but then if it appears in several places in your application you have a lot of duplication.
Speaker 1
15:05
So when I change this to ViewComponent, and again, nothing particularly special about ViewComponent. It's just this idea of packaging up the view-related logic with the view itself, I could have that physician.active.ordered a certain way, query just in 1 single place. That eliminated all of my DRY problems, and my awkwardness, and the controller problems, and all of that stuff. Obviously I imagine Flex could solve that same problem too.
Speaker 2
15:42
Yeah, of course. And that query could also be based on, it could either be a global query like physicians.all or physician.all, or it could be based on some input that that view accepts or that view component accepts. So, each of these view classes are like normal Ruby classes.
Speaker 2
16:09
So you can just define an initializer, for example, that takes the current account or something like that. Actually, current account is probably going to be better to come from your view context. But you could make, like, a user form component that takes as 1 of its arguments a user object. And then everything else is based on that input.
Speaker 2
16:38
So the initializer takes the user object, stores it in an instance variable, and then the template can refer to a method that references that user object and then builds a form for you.
Speaker 1
16:51
Yeah, I like that. 1 thing that I don't like about views and partials, all that, is when you encounter an instance variable in a view or a partial, it's like, where did this come from? It's a total mystery guest.
Speaker 1
17:10
Whereas if you encapsulate it, it's no longer a mystery. You don't have very far to look to find the origin of that instance variable.
Speaker 2
17:19
**Timer** Right. In Flex, an instance variable has to have come from the view that you're looking at. Like, it can't be inherited from the controller or something like that.
Speaker 2
17:32
So, if you're going to render a view from a Rails controller, and actually Flex is not dependent on Rails. Flex only has a dependency on Sitework, And you can use it in any Ruby application. But there is, like, an extra library, flex Rails that gives you some kind of interoperability with Rails. So, if you're using this and you're rendering from Rails, instead of just saying, like, so, usually your controller, you would set up some instance variables, and then you just let Rails figure out the correct view to render.
Speaker 2
18:13
And it goes and finds a view in your views folder and renders that ERB view. With Flex, instead of setting up instance variables in your controller, you actually call render, and you would pass it the name of the view you want to render. So it might be like articles index. And then you say, so render articles index dot new.
Speaker 2
18:35
And inside that, you then pass it all of the variables that you want it to render with. So, you might say, as a keyword argument, articles is this article.all or something like that. And then back in the articles index view, you know that the articles argument, like the articles instance variable came as an argument to that view and it couldn't have come from somewhere else. So it's really easy to find, like, kind of encapsulate that.
Speaker 2
19:08
Does that make sense?
Speaker 1
19:10
Yeah, yeah.
Speaker 2
19:11
You can also test these views in complete isolation from controllers. Because a view takes specific input and only works on that input, you can run it in a test environment and just, like, directly call it with input and it will always produce the same output because it doesn't require that you set up your whole Rails application and render that view and go through the controller and everything. It's fine to just render a view on its own.
Speaker 1
19:41
**JASON LENGSTORF** Yeah, I think that's a really compelling idea, too. I think, You know, for most of my views, there's not enough going on to justify a test because it's just static. Or I would cover it with a system test.
Speaker 1
19:56
But for those cases where there is some non-trivial view related logic, that's so great to be able to test it on its own without having to spin up the whole stack.
Speaker 2
20:10
The other thing that you can do, which I think is really powerful, is you can define a view that exposes an interface to another view. So you know when you call a Rails partial, you say render, and then you put in the partial name. And you can then pass in some arguments.
Speaker 2
20:35
And then you say do, and then you can output the content of that partial. So wherever the partial yields, your content will be in that partial. So in Flex, you can do the same thing. But when you say do, you can then pick up an object that represents that component.
Speaker 2
21:00
So I could say, like, render tab group do, and then I can pick up T, and then within that block, I can say T.tab, and I can pass it the name of my tab, and then another do block, and I can put the content for that tab. And I can say T.tab again with another name in the content. T.tab with another name in the content. And what this is doing is it's calling the tab method on my tab group view.
Speaker 2
21:31
And that knows how to output a single tab. So it's going to add, it's going to take the name and put that in the tab list across the top. And it's going to take the body and it's going to put it in a tab body element that's going to be shown and hidden depending on which tab you're viewing. So you can kind of encapsulate a more complex component that has various, like several parts to it so that when you're using it in other parts of your application, You don't need to know about which elements and which classes go where.
Speaker 2
22:05
All you need to do is use this simple interface that you've defined. So Flex makes it really easy to do that.
Speaker 1
22:14
Okay. Yeah, I followed everything you said. I can't immediately think of a use case where I would use that, but I understand mechanically how that would work. So that makes sense.
Speaker 1
22:30
Okay. And how long have you been working on flex?
Speaker 2
22:35
I've been working on it since I think for about 6 months now
Speaker 1
22:42
Yeah, and I saw that it has like that has a lot of github stars it has Yeah 659 stars. How did you get the word out about this?
Speaker 2
22:52
Mostly through Twitter. I kind of just shared a lot of progress as I was building it. I posted quite early on this, like, idea for building views.
Speaker 2
23:07
And it's not a completely original idea for building views in Ruby. There are a number of projects, or there have been a number of projects, most of them aren't maintained anymore, that do a similar kind of thing. But they all had various limitations and didn't quite work the way that I wanted them to. So I started this from scratch.
Speaker 2
23:31
And yeah, I just kind of built. I wrote a view exactly as I wanted to write it, and then I figured out how to make Ruby interpret that and actually output real HTML that was valid. And then I spent a few months working on performance and working on mainly integration with Action View, which is quite complex because It just works in such a completely different way to flex.
Speaker 1
24:03
Oh, I see. Yeah, I just want to say that even though it's arguably more verbose, I much prefer your way of where in a controller, the view gets rendered explicitly, and you pass it the values that it gets. Because it's like, when would you ever want to call a method?
Speaker 1
24:26
And the way that you pass the values to the method is you just set some global variables, and then the method just catches those global variables somehow. MATT GAUNTENGEN-MARTINEZ-SWEETSYLICK
Speaker 2
24:36
It's a bit strange, and you can kind of follow it down to 1 layer, like down from a controller to the view that represents the page. But once you realize that actually partials that are rendered within that view also have access to those instance variables, it gets really weird. Because you might build a partial.
Speaker 2
24:58
You could copy something from your view and extract it into a partial so you can reuse it. And then you reuse it in a different template that's coming from a different controller. And then suddenly your site is broken because that partial was depending on an instance variable that was set up in a completely unrelated controller. So that kind of thing is a whole class of problem that I wanted to eliminate by saying you can only access instance variables that are explicitly sent to the view.
Speaker 1
25:33
Yeah, I have very few criticisms of the architectural decisions made in Rails, but that would be 1 of them. And yeah, it's fine when the app is young and there's not a lot of stuff going on. But once it gets complex and there's a lot of partials, it's pretty easy to make mistakes and pretty easy to create view scenarios where it's really hard to follow.
Speaker 2
26:02
Yeah. Yeah. There are some other advantages that are quite tricky to explain, but I might give it a go to having a system like flex. 1 of them is probably best explained by talking about flex markdown, which is a kind of extension to flex that I've built.
Speaker 2
26:30
Okay. And what this is essentially is it's a very, very simple component. I think it's like maybe 50 lines long or something like that. It's just a flex component.
Speaker 2
26:44
But you can and it's a component that takes 1 argument, that's the string, a string of markdown, and it produces HTML. But it produces the HTML by going through these, like, flex tag method calls. So, if it's producing an unordered list, it calls the method ul. If it's producing a list item, it calls the method li.
Speaker 2
27:13
And so if you define your own markdown class, so like my markdown. And you say, I'm going to inherit from flex markdown. But in my markdown class, I want to apply these classes to unordered lists. I want to apply these classes to heading ones.
Speaker 2
27:33
So you can just define the method, h1, and pass it the classes that you want, like text Excel or font bold, if you're using Tailwind, for example. And then when you render your own Markdown component with a string of Markdown, it's going to produce HTML that used your definition of those elements. If that makes sense? You just define like h1 equals super but with class text XL.
Speaker 1
28:07
I think we're getting to the point where I'd have to see it and work with it in order to to grasp it.
Speaker 2
28:12
OK.
Speaker 1
28:13
Yeah. But I actually want to totally change topics and ask you something different, if you don't mind. I'm curious about your time at Shopify because that's obviously an organization everybody's heard of and you worked there for quite some time. And it's a totally different scale from what I'm used to.
Speaker 1
28:33
You know, most of my jobs, basically all my jobs that I've ever had, have been at relatively small companies on small teams. So I'm curious, and the answer is probably more than 1 thing, but what did you work on while you were at Shopify?
Speaker 2
28:49
Yeah, I worked on so many different things. I'm trying to think what are some good examples. So I was there for probably nearly 5 years.
Speaker 2
29:07
I initially joined the privacy engineering team. And on that team, I worked on a bunch of different projects. 1 of them was related to the sale of cannabis in Canada. I worked on this big project to set up a instance of Shopify that could be used safely so that none of the data could leak outside of Canada at all.
Speaker 2
29:43
Like doesn't use any US services, isn't hosted in the US at all, and doesn't send any customer data outside of the US. So that was, like, a really big project that I worked on a really small part of, which was to audit all of the kind of external network requests that were made. So it's this just huge, huge Rails app, I think millions of lines long. Something like 13 years old at the time.
Speaker 2
30:19
Wow. And we just had to set up this whole new instance of it.
Speaker 1
30:24
Wait, where, I don't understand what this Rails app was. Where did, what was it? Where did
Speaker 2
30:28
it come from? Shopify core.
Speaker 1
30:30
Oh, Shopify, Okay, I see.
Speaker 2
30:33
Yeah, so I don't know anything about this project now, but I'm pretty sure it's public knowledge that we had this contract. I really hope it's public knowledge. But Yeah, so that was interesting.
Speaker 2
30:50
That was like 1 of the first things I worked on was figuring out how to audit this massive Rails app for all these external network requests. So that we could check, like, does this network request include any customer data and is it going to a service that might be located in the US or, like, outside of Canada somewhere? And then do we need to build a path in the application to avoid doing that request when we're in this isolated environment? So that was a really interesting project.
Speaker 2
31:27
After that, I spent a lot of time working on a system for managing GDPR data subject requests. So if someone asks Shopify, please, can I have a copy of my personal data? Or please can you delete my personal data, then because of GDPR, we have this obligation to, or Shopify has this obligation to, like, carry out those requests in a certain amount of time. And so I was working on a system that could kind of manage these requests and distribute them between all of our services.
Speaker 2
32:15
So we had a bunch of internal services that, like, some of them were Rails-based, some of them weren't. And it was just a case of, like, being able to have a kind of source of truth that was able to say, for this request from this person, I know that all of these applications have carried it out, and all of these external applications have carried it out, etc.
Speaker 1
32:46
Okay. And how did you approach that? That's like, that seems like it could be complicated.
Speaker 2
32:54
Yeah, it, I mean, it was a lot of like exploring that domain problem. That domain problem, like figuring out how to communicate between all of our services, figuring out how the requests would end up coming in, like what were the entry points, and then just like building out all the logic and all of the jobs to do all of this processing. I remember 1 really interesting kind of naming story I have from this is we used to have this model called requests that were requests from users.
Speaker 2
33:41
And we had another model called services that were the services that had to, like, carry out these requests. And we had a model that joined them that was called Service Request. And it's a really confusing name. It didn't really tell anyone what it was doing.
Speaker 2
34:04
And we spent some time thinking about this and ultimately came up with the name assignment for that join. And I just think that that was Like just such a great example of a name completely changing how you think about something because once we started saying like This request has many services through assignments It's just obvious like what that means like an assignment is like this this clear join table this clear connection between those concepts. So I think that was interesting.
Speaker 1
34:40
Yeah, I like that. Something I learned at some point is like there's 2 ways to name things. 1 way is to like recognize existing concepts and make your names match those existing concepts, which as obvious as it sounds, not everybody does all the time.
Speaker 1
34:59
But then there are other things like this service request, what you were originally calling a service request.
Speaker 2
35:06
Right.
Speaker 1
35:08
You know, you were doing something kind of logical. You were recognizing 2 things, services and requests, and when you connect them, well, I guess it's a service request. But when you applied a higher level of imagination to it, you realize that you could give it this other name.
Speaker 1
35:27
It wasn't a recognition of an existing thing. It was kind of the invention of this new concept called an assignment, or at least a reimagining of an existing concept, looking at it a different way, maybe.
Speaker 2
35:42
And it was kind of applying a metaphor from like to do list world, I guess, like project management world. That just seems so applicable to our problem.
Speaker 1
35:59
Yeah. So I think that realization that sometimes naming things isn't a recognition, it's an invention, is a really helpful 1. Yeah. Yeah, okay, so you worked on that GDPR stuff, what else?
Speaker 2
36:15
Yeah, to be honest, that took a lot of my time there. And it involved, like, not only building this, like, service that was a Rails app that would manage these requests, but also, like, integrating them with various other services. So I spent a lot of time working on, like, a library that would allow other Rails apps to communicate with this app.
Speaker 2
36:47
And also kind of, like, figuring out how to make this problem of finding all of your data that relates to a particular person and acting on it in some way much easier for the maintainers of other applications. So 1 of the projects that I worked on towards the end was a library that would kind of allow you to describe your data with a privacy schema. So I could say, like, these are all the database tables that I have that have personal data in them. And these fields have personal data.
Speaker 2
37:29
And also, these are all of my data subject types. So it might be like a merchant or a shop customer or an employee or a member of staff. And you can say these fields relate to these data subject types. And then you could say these tables are the entry points for these data subject types.
Speaker 2
37:55
So, that might be a customer's table is the entry point for a customer. Or, like, the staff users table is an entry point for a member of staff. And then you could define relationships from those entry points down to the tables that had like private personal information on them. In fact, the schema would force you to do that because it could say, hey, you have got this table that has this field on it that's private information for a shop customer, but there's no way to find that table from the customers table.
Speaker 2
38:39
So, it would kind of force you to define all of these relationships. And then from that schema, you could start a query. So you could say, I need to query for all of the shop customers data for, like, this particular customer. And it would kind of give you this custom enumerator that would give you batch relations to each of those tables that were linked in a single go, like in this enumerator, which meant you could create a job that would do things like delete that person's data or copy it somewhere.
Speaker 2
39:23
So it was kind of like an exploration into how do I, Like, what is the essence of the problem that people are trying to solve? And how can we take all the complexities of building, like, erasure jobs or access jobs and try to automate as much of it as possible. And also eliminate bugs. Because it's really easy to, like, miss something if you've got a lot of code going on.
Speaker 2
39:56
If you have, like, 20 different jobs that are all calling each other, it's really, really easy for 1 of those jobs to be misconfigured or to have an n plus 1 or to not do correct batching. So by separating it out and making this schema and then making this query interface, you could build your erasure job in like 10 lines of code because it knew everything. It could talk to Active Record and see things like, okay, you're trying to erase this field, but this field is required. Like it can't be null.
Speaker 2
40:36
So we can't set it to null. It's also unique. So we can't set it to redacted. So we have to generate a random replacement for it and, like, specify that it's redacted.
Speaker 1
40:49
Oh, wow.
Speaker 2
40:49
But with this random replacement. So That kind of thing. And trying to make that library so that it can operate across a bunch of different apps that are developed by different people, different teams, different times.
Speaker 2
41:06
That was kind of what really got me into kind of digging deeper into metaprogramming and library development.
Speaker 1
41:15
Yeah, I can see how all that would take quite a lot of time. It sounds like that's something you worked on for maybe multiple years, right?
Speaker 2
41:25
No, that took, like, the initial prototype for that took like a few days. Because for all the... So much of that stuff...
Speaker 1
41:36
Oh, I was talking about just all the GDPR stuff in general.
Speaker 2
41:40
Oh, right, yes. The GDPR stuff in general took years. But that prototype took a few days.
Speaker 2
41:45
Because it was mostly able to piggyback off of active record. Like it's so easy to like query active record schema for like a list of fields, for example. Or given a field on a table, like is this like what are the constraints for this? Does it have a null constraint?
Speaker 2
42:05
Does it have a uniqueness constraint?
Speaker 1
42:08
Oh, I see.
Speaker 2
42:10
Yeah. And we didn't have to worry about foreign keys because we don't use, we didn't use foreign keys at Shopify.
Speaker 1
42:18
Oh, really?
Speaker 2
42:18
For reasons. Yeah.
Speaker 1
42:21
For reasons.
Speaker 2
42:21
I think for scaling reasons. I remember reading about it, but I can't remember exactly why.
Speaker 1
42:28
Yeah. Well, that's interesting. That, like, that sounds terrifying, but maybe if I read how they do it, it wouldn't sound as terrifying. I don't know.
Speaker 2
42:38
It's not that terrifying. Yeah. I think it was just a case of using.
Speaker 2
42:45
I can't remember the details now. I wish I could because I found it really interesting when I read about it. But I remember when I read it, I was like, yeah, that makes sense. That makes a lot of sense.
Speaker 1
42:54
OK. Well, different question for you. I see that you have what looks to be a pretty nice mic, a nice mic stand, and a pop filter and all that stuff. I'm guessing you didn't buy all that stuff specifically for this podcast episode.
Speaker 1
43:15
So are you somebody who, well, I'll ask it this way. Why do you have that?
Speaker 2
43:24
I have it because, why do I have it? When Shopify went fully remote during the pandemic, they said everyone needs to work from home now. They had this big push for everyone to get their remote work set up, really, really tuned in.
Speaker 2
43:50
And so they gave everyone a budget to try to improve their home internet connection or get a monitor or desk or whatever you need to improve your setup. I already had a really good monitor at a desk and a chair because I was already working from home. But 1 thing I thought that would help would be to sound better on video calls. So I used that budget to get a microphone.
Speaker 1
44:19
Yeah, I think that's a really good idea. Yeah. I think about that sometimes, just like your physical environment and all that stuff and how it affects your mood and productivity and all that stuff.
Speaker 1
44:33
I myself, yes. Yes. Obviously I have like a good microphone because I host a podcast. But I have like a really nice, adjustable height standing desk that I spent kind of a lot of money on because it's like I'm going to use it every day for the next, I don't know, a couple of decades maybe.
Speaker 1
44:57
I mean,
Speaker 2
44:58
when you really think about it, You didn't spend that much on it. Like how much money do you spend on your setup compared with like I don't know like taxi driver needs to buy a taxi like that's thousands and thousands of tens of thousands of pounds. You're working in this environment every single day.
Speaker 2
45:19
I think it makes sense to invest in it.
Speaker 1
45:21
Yeah. Yeah. And for a long time I was working out of my like, dark dingy basement, and now I'm finally in my own office where my background looks much more professional. I still have to decorate the wall behind me because it's been noted that I look like I'm in a void, just a white void.
Speaker 1
45:43
But a white void is better than a dark basement, I think.
Speaker 2
45:48
That's kind of what I've got going on here, is the dark basement look. No, I'm actually, we're trying to convert our house into, like, we're converting an old garage into an office space. But in the meantime, I'm kind of working out of the living room.
Speaker 1
46:08
I see.
Speaker 2
46:09
So that's all right when the kids are at
Speaker 1
46:11
school. Uh-huh.
Speaker 2
46:15
And when they're not, I have noise cancelling headphones.
Speaker 1
46:18
Yeah, that's a benefit of where I am. I'm out in a, I don't know if you guys have these in England, but I'm in a pole barn. You know what that is?
Speaker 2
46:28
No, what's that?
Speaker 1
46:30
Yeah. So a pole barn, we have these a lot in rural America. It's a metal barn. That's usually used for storage.
Speaker 1
46:40
Maybe you'll keep vehicles in there. If you have like a 4 wheeler or something, you'll keep it in there. Lumber, you know, whatever extra stuff you have, you'll keep it in your in your pole barn. So when we bought this house, it came with a pole barn.
Speaker 1
46:55
And then over the last few months, this office has been built in the pole barn. We sectioned off like a 12 by 18 space here, got it insulated and heated and all that stuff. So this is a nice separation from the family because it's not just my kids. My wife will come talk to me and stuff like that.
Speaker 1
47:14
And now there's a barrier. It's raining right now. So she'd have to trek through the rain in order to come talk to me.
Speaker 2
47:21
Oh, so it's not attached to the house.
Speaker 1
47:23
Yeah. No, it's a couple of hundred feet away. Yeah.
Speaker 2
47:26
Right. That's great. So you got a bit of a commute there. Yeah, my
Speaker 1
47:32
friend, my friend works out of his basement right now and I suggested to him, he doesn't have like a lot of property, so I suggested in his backyard he does 1 of those like sheds that you buy and convert into an office. But I suggest that he put it really high up on stilts and he could get to it via a rope ladder. And then once he's up there, he can reel in the rope ladder.
Speaker 1
47:55
So nobody can get to him up there. I thought that was a really good idea.
Speaker 2
47:59
That's great. Also like good upper body strength, climbing up a rope ladder every day.
Speaker 1
48:04
Definitely gives a little exercise in the morning. Yeah. Yeah.
Speaker 1
48:10
Well, good. We covered I think my favorite topic that we covered today was was the flex stuff. 1 of my favorite things about this podcast is I can find things I don't understand and then just get the person who made that thing and ask them directly to explain it to me. So that's been really great.
Speaker 1
48:28
I'm sure it's been good for other people. And obviously I'm sure people are listening to this who haven't even heard of it before and they can go give it a try. That's maybe a good segue to my final question, which is, is there anywhere you'd like to send people to check out your stuff and all that?
Speaker 2
48:45
Yeah, sure. So I'm quite active on the Masteredin Ruby.social community. So you can find me on I think it's Ruby.social slash at JoelDraper.
Speaker 2
49:05
You can also find me in a bunch of Ruby discords, particularly the stimulus reflex discord where we have the Flex channel. So if you have any questions about flex, that's a great place to kind of pop in and ask questions And of course flex can be found online at flex dot fun, which is spelled with a pH pH le x dot FUN
Speaker 1
49:30
So you couldn't get a dot pH you in?
Speaker 2
49:35
No, yeah, that would have been
Speaker 1
49:37
It would have been more consistent
Speaker 2
49:40
More consistent. Yeah
Speaker 1
49:42
Anyway flex.fun. We'll put that in the show notes, of course and Joel. Thanks so much for coming on the show.
Speaker 2
49:48
You're welcome. It's been great to be here. You
Omnivision Solutions Ltd