<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Own it - A blog from Adrian Marin]]></title><description><![CDATA[Sharing my lessons on becoming a thriving #indiedev.

 🚀 Launching Avo into the world! - 🥑 A beautiful, easy-to-use [Ruby on Rails admin panel framework](http]]></description><link>https://blog.adrianthedev.com</link><generator>RSS for Node</generator><lastBuildDate>Wed, 22 Apr 2026 02:20:43 GMT</lastBuildDate><atom:link href="https://blog.adrianthedev.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[SF Ruby 2025 and the Thousand People Framework]]></title><description><![CDATA[I think it's important that the Ruby community knows what just happened in San Francisco last week.
400+ Rubyists got together and shared ideas and visions. They exchanged opinions and presented the past, present, and future of Ruby.

I went to very ...]]></description><link>https://blog.adrianthedev.com/sf-ruby-2025-and-the-thousand-people-framework</link><guid isPermaLink="true">https://blog.adrianthedev.com/sf-ruby-2025-and-the-thousand-people-framework</guid><category><![CDATA[Rails]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[conference]]></category><category><![CDATA[community]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Wed, 26 Nov 2025 11:13:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764154214446/3da83a8a-d2c4-4895-aff0-9efed14748f7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I think it's important that the Ruby community knows what just happened in San Francisco last week.</p>
<p>400+ Rubyists got together and shared ideas and visions. They exchanged opinions and presented the past, present, and future of Ruby.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764154303642/76bc4078-7973-4f01-859c-49017a51c708.jpeg" alt class="image--center mx-auto" /></p>
<p>I went to very few talks (lately, the hallway track is the one that's getting most of my attention) but was impressed (no surprise there) by <a target="_blank" href="http://github.com/palkan">Vova</a>'s talk "Rails X". He did such a good job going through the current state of Ruby tooling, highlighting some areas where we need to pay a bit more attention to detail. I love the whole vision and how he showcased our community members and their work.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764154476546/da865664-2523-4435-9967-1d3447d797da.jpeg" alt class="image--center mx-auto" /></p>
<p><a target="_blank" href="https://avohq.io">Avo</a> was there too. <a target="_blank" href="https://x.com/paul_ionut_bob">Paul</a> and I prepared a cool booth where quite a few guests came to learn more about Avo, see demos, and talk through issues or problems they'd encountered along the way. We brought Romanian <a target="_blank" href="https://ro.wikipedia.org/wiki/Biscui%C8%9Bi_Eugenia">chocolate biscuits</a> and <a target="_blank" href="https://ro.wikipedia.org/wiki/ROM_\(ciocolat%C4%83\)">chocolate</a>, and showed off the new design which we have ready for the next release.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764154681286/bb034ebe-2701-4592-a872-340921f024e5.jpeg" alt class="image--center mx-auto" /></p>
<p>The venue was pretty eclectic too. Fort Mason is a former military fort now administered by the National Park Service (we even shot an <a target="_blank" href="https://www.youtube.com/watch?v=DcqgcMxas7o">impromptu podcast interview</a>). The event had some cool surprises like a space where you could get your t-shirt screen-printed live in front of you, a secret room where you could play games using Ruby, and the <a target="_blank" href="https://therubypassport.com/">Ruby Embassy</a> with its event stamp. After collecting that one, you could visit the sponsor booths to get extra stamps.</p>
<p>After the event, there were several activities set up. AngelList held a hackathon at their HQ, some went for a swim to Alcatraz in the morning, and some (like myself) rented e-bikes and took a ride around the waterfront, across the Golden Gate Bridge, and into Sausalito. It's a tour I won't forget anytime soon.</p>
<p>But the most important thing that happened at <a target="_blank" href="https://www.sfruby.com">SF Ruby</a> was the statement it made.</p>
<p>If you've crossed paths with me and we've gotten deep into conversations about Ruby, Rails, and the current state of affairs, you've probably heard me talk about the "One Thousand People Framework". Don't get me wrong, I love the "One Person Framework" approach. It enables small teams to be incredibly nimble and ship value at an unprecedented level. There are so few frameworks and ecosystems out there that can do that.</p>
<p>While this tagline helps a lot with adoption at the bottom of the funnel (single developers and small teams), I don't think it does justice to larger teams (100 people or more). Those companies where tech stack decisions are taken with much larger considerations in mind. Where they ask questions about what support exists at that scale.</p>
<p>I know what you're thinking: "Why should I give a damn about that?", but I'd say it's more important than ever nowadays.</p>
<p>It's important because these huge companies have the manpower and resources to actually push the language and framework forward. They're the ones that can fund 40-person teams to improve Ruby and Rails like <a target="_blank" href="https://shopify.com">Shopify</a> does. Without Shopify, Ruby and Rails would be worse off.</p>
<p>Another big idea I stand behind is that <strong>optics matter</strong>.</p>
<p>It matters what we put out there into the world. It matters what we say and how we frame things. It matters that Ruby looks like a viable solution going forward for new developers and brings them opportunities. Same for companies who haven't made their bets on their tech stack yet.</p>
<p>And I think this is what happened at SF Ruby last week.</p>
<p>SF Ruby made a statement: that Ruby and Rails is still alive and kicking, powering big and upcoming companies. The new generation of Shopify-level companies. Companies like Chime, <a target="_blank" href="http://Bolt.new">Bolt.new</a>, Intercom, Gusto, PlanetScale, and others. SF Ruby showed that Ruby and Rails is still powerful in the Bay Area and around the world.</p>
<p>And that's one of the most important things that could have come out of this event.</p>
<p><a target="_blank" href="https://x.com/inazarova">Irina</a>, <a target="_blank" href="https://www.linkedin.com/in/amanda-kinney-santibanez/">Amanda</a>, <a target="_blank" href="https://x.com/_senkovskiy">Anton</a>, <a target="_blank" href="https://www.linkedin.com/in/stancheta/">Steven</a>, <a target="_blank" href="https://www.linkedin.com/in/kendecanio/">Ken</a>, <a target="_blank" href="https://x.com/camertron">Cameron</a>, <a target="_blank" href="https://www.linkedin.com/in/garyhtou/">Garry</a>, and the rest of the <a target="_blank" href="https://evilmartians.com/">Evil Martians</a> and <a target="_blank" href="https://sfruby.com/about/#:~:text=%F0%9F%99%8B%E2%80%8D%E2%99%80%EF%B8%8F-,Meet%20the%20org%20team,-Here%27re%20the%20main">organizing team</a> did an incredible job putting on a swanky event with small-conference vibes but big implications. Thanks everyone for the fantastic job you did</p>
<p>I hope to see it organized again and again for a long, long time.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155394905/d0cc998a-a22b-427e-a04d-b044794e168b.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155414183/698bbe12-0aa3-4cd0-9233-cd8a7d12d817.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155423364/19aff6c0-df10-4517-8223-6a77eb719e9e.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155429513/31f0198d-239c-480d-8e42-9909f89b4957.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155436795/57d95e19-7c22-4362-b2ae-2c63f272dcfc.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155440601/eb049553-5d2a-43e9-b4c1-79f13ea019d1.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155448388/7afb67d1-157c-4811-bbfa-52012aa1f7d8.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155452284/9148c5fd-a7b2-4501-b6c8-95b37729ff94.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155461947/9c4f3ae2-315e-4582-aa19-6995773874c8.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155468243/7b883e98-f9df-4ab9-b951-9ae7f280a016.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764155513839/5436ce4e-68f1-430c-9968-51f36bd9f31f.jpeg" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Friendly is taking a break]]></title><description><![CDATA[Tl;DR;
We're taking a break with Friendly.rb. We had three beautiful editions, incredible fun, and learned so much in the process. This happening changed us, the hosts in ways we could not imagine. We're taking a break because things have happened in...]]></description><link>https://blog.adrianthedev.com/friendly-is-taking-a-break</link><guid isPermaLink="true">https://blog.adrianthedev.com/friendly-is-taking-a-break</guid><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Fri, 19 Sep 2025 10:40:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758277083966/cc4d111f-da9c-49f8-853d-2fa051cb5f7c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-tldr">Tl;DR;</h3>
<p>We're taking a break with Friendly.rb. We had three beautiful editions, incredible fun, and learned so much in the process. This happening changed us, the hosts in ways we could not imagine. We're taking a break because things have happened in our lives that require our focus.</p>
<h3 id="heading-a-thought-sprouted">A thought sprouted</h3>
<p>Let me paint you a picture.</p>
<p>It's late 2022. I went to <a target="_blank" href="https://wrocloverb.com/">Wroclove.rb</a>, and was mesmerized by the community and the event. I learned about <a target="_blank" href="http://RubyConferences.org">RubyConferences.org</a> and was checking it out to see which was the next event I could go to. Sadly, there were almost none in Europe. Rails World wasn't a thing. <a target="_blank" href="https://euruko.org/">Euruko</a> and <a target="_blank" href="https://brightonruby.com/">Brighton</a> just came back after a break. Immediately my mind started working. "What if I put on an event like that?" "Would I be able to do it?"</p>
<h3 id="heading-a-conference-was-born">A conference was born</h3>
<p>I started contacting conference organizers. Andy was the one of the first. I can't tell how much that call changed the course of Friendly. <a target="_blank" href="https://andycroll.com/">Andy</a> taught me about the diversity problem in events.</p>
<p>He taught me that being the biggest event by number of attendees may not be the most important metric of a successful event. But most importantly, he opened my eyes that I could make any kind of event. I could make the event that I wanted to attend. That made it so much more appealing to me than anything else 🙌</p>
<h3 id="heading-assembling-the-team">Assembling the team</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758277148235/4b3431b8-423d-4109-a641-4061968204ac.jpeg" alt class="image--center mx-auto" /></p>
<p>By then I had a group of friends with who I had weekly calls with for about a year now. People nowadays call it a mastermind group, but we were not masterminding anything, relly 😅 It was a support and accountability group with a big focus on the Ruby community.</p>
<p>I had <a target="_blank" href="https://avohq.io/">Avo</a> and <a target="_blank" href="https://ghinda.com/">Lucian</a> was just starting <a target="_blank" href="https://newsletter.shortruby.com/">Short Ruby Newsletter</a>. We've had conversations before about putting on an event in Romania, but had no real catalyst to get started</p>
<p>I pitched the idea and everyone was pretty much on board with it from the get go. So we started brainstorming.</p>
<p>The first thing we needed is a name. "What should we call it?" "Bucharest.rb? Romania.rb?" We probably had weird proposals like Carpathians.rb and others. We did check <a target="_blank" href="https://balkanruby.com/">Balkan.rb</a> but that was taken 🫣 Balkan.rb was on a sabatical at the moment too.</p>
<p>So I proposed the idea "How about we call it Friendly.rb? It would just set the tone of the whole thing 🙌 We call it Friendly, we will be friendly, and hopefully friendly people will come.", I said not knowing exactly how important that would become. That day we were set on the name. We got in touch with a designer and went with our Romanian folkloric motifs and quickly spinned up a website and released ticket sales.</p>
<h3 id="heading-speakers">Speakers</h3>
<p>Remember the diversity talk I had with Andy? I took a big mental note of that. We wanted to have a very balanced mix of speakers form all facts of life, all genders, some well-knownk and some just starting out.</p>
<p>I was always afraid that we wouldn’t be able to have a great line-up every year. But I think we managed to do that.</p>
<p>We were very lucky to have had so many fine folks speak at Friendly. Thank you Xavier, Elena, Jeremy, Jason, Naijeria, Nick, Rosa, Tom, Greg, Irina, André and the rest of the speakers for coming all this way to speak. I know for a fact that many people came to see you, not us.</p>
<h3 id="heading-why-were-taking-a-break">Why we're taking a break</h3>
<p>Many are asking "Why?". The reason is pretty simple: Life changed for us.</p>
<p>Jakob moved to Germany. During the time I know him he moved to different cities three times. He just loves trying out new things.</p>
<p>Stefan moved up the career ladder and is increasingly more busy and has less time to focus on Friendly stuff.</p>
<p>Lucian is busy as well with Short Ruby. His work requires more of his time and the slice of free time he has is split between family and other things (Friendly is in the "other things" slice).</p>
<p>I now have two wonderful kids. One of which is a boy toddler who doesn't care about anything and anyone in this world. His latest passion is to be naked all day and pee in the grass "like a dog". I have the business I want to further focus on and doing Friendly takes away much of that focus.</p>
<p>So our priorities changed.</p>
<h3 id="heading-it-takes-a-lot-of-focus">It takes a lot of focus</h3>
<p>During these past three years I stopped speaking about how much time Friendly takes from us to happen and started talking about focus, because focus is much more precious than time.</p>
<p>Speaking about time, I estimate that in the first year it took at least one and a half months of my productive, work-related time to make Friendly happen. You read that right. One and a half months. Maybe more, I don't count my hours.</p>
<p>The second year a little bit less, and probably the last year, less.</p>
<p>In '25 I left my kids and wife at my in-laws (where we spend some part of the summer) for about three weeks before Friendly to come to Bucharest to finish up Friendly. That proved out to be more difficult, emotionally, than I anticipated.</p>
<p>But anyway... Focus is the thing that I lost. Because I wanted to make a more-than-nice conference and wanted to offer our guests an very welcoming experience I knew that I wanted things in a certain way.</p>
<p>I wanted the swanky venue. There was no way I would compromise in a boring hotel lobby or corporate building.<br />I wanted a great video crew. I wanted to capture the talks that were happening on stage but also the vibe off-stage too, and I wasn't going to leave something that important to chance or to an un-experienced crew.<br />I wanted our guests to experience much of that Bucharest has to offer. We started organizing guided walking tours after the next day.<br />I wanted a great after-party. I wanted everyone to eat and drink.<br />I wanted the off-conference time to be spent nicely in the city so we prepared a list of attractions, food, drinks, and coffee places for folks to go to, meet and hang out.<br />I wanted to have quirky talks so we had talks about where the Roma people came from, Mental health, and plenty of SaaS.<br />I wanted to have special activities like Jakob's game show (all props go to Jakob for that), Lucian's Coffee demo, and Julian's Music and game building with Ruby talks.<br />I wanted to show folks our mountains, so every year, on day three we got on a train in the morning, went to the mountains, visited a castle, had some local food, and got back in the evening.<br />I wanted everyone to leave with a smile, (at least) a new friend, and them believing they've been seen, heard, and appreciated.</p>
<p>All of that takes time and focus. Someone has to make sure every second that those things will happen. Every event organizer know most of the time you have multiple touch points with every vendor. You need to check up on them. You need to ask for details. You have to ensure things are happening in a certain way.</p>
<p>We don't have managers at Friendly. No hierarchy. If you have an idea and want to have something happen, you go out and do it. You might have a review (in the form of me and my opinion 😅), but if you have an idea, you have to implement it yourself.</p>
<p>To cut it short... it takes a lot of time and focus to ensure things go properly and people feel welcomed.</p>
<h3 id="heading-what-about-passing-the-baton">What about passing the baton?</h3>
<p>We thought about "giving" it to someone else, but that's not the profile of the conference. We wanted to make it our way. I'm not sure that anyone else could do it in that way.</p>
<p>Don't get me wrong... someone else might do it better than us, and that's fine, but just not in our way. I would very much prefer having three editions that rocked and it's done rather than have two era's with different types of polish and different vibe. We didn't want Friendly to be that rock band which didn't age ok and still tries to "rock on" when they should just retire gracefully. I'd rather us remember Friendly for the incredible happening that it was.</p>
<p>The event where everyone hugs when they meet.<br />The event where smiling is not mandatory but happening.<br />The event where people come to create connections.<br />The event where folks feel like at home.</p>
<h3 id="heading-sponsors">Sponsors</h3>
<p>I want to take a moment to thank the sponsors.</p>
<p>And I want to urge you to go out and say thank you yourself to them. Seriously, when you meet anyone from a company that you see sponsoring events, go to them and say "Thank you for sponsoring our community!" That's it! It's going to make their day better and make them do it more. Only with their help we will be able to continue to put on these events and make the community better.</p>
<p>Without them we would not have had the funds to add this level of polish to our event or be able to create that warm environment for everyone to connect.</p>
<p>So thank you Andy Croll, Flagrant, Nick Sutterer, Softia, Evil Martians, 2Performant, Prowly, RoR vs Wild, Sibiu IT cluster, Wolfpack, ClickFunnels, Typesense, Stripe, Buzzsprout, Bitzesty, Trmnl, Agile Freaks for all your work and investment.</p>
<h3 id="heading-ruby-triathlon">Ruby Triathlon</h3>
<p>This is something that happened naturally, and not planned. I hope some other event comes and fills the Friendly slot in September. I hope it will carry the torch and be the island of friendlyness and small-conference-vibes between the giants like Euruko and Rails World.</p>
<h3 id="heading-the-ruby-passport">The Ruby Passport</h3>
<p>We got something very powerful out of all this conference planning and attending. We have the Ruby Passport. An in-real-life way of keeping track of the events we visit and connecting with our community. For now it's a physical mock Passport which you can stamp at each conference and claim digitally on <a target="_blank" href="http://rubyevents.org">rubyevents.org</a></p>
<p>There's plenty of work to be done there and it's an open-source project so let's meet on the <a target="_blank" href="https://github.com/rubyevents/rubyevents">repo</a> and make this community even better.</p>
<h3 id="heading-future-plans">Future plans</h3>
<p>Many ask me if we want to pitch for <a target="_blank" href="https://euruko.org/">Euruko</a>. My answer is "No!" We ran a great 120-140 people event. I'm not sure we want or are ready to run a 500-600 people event. So no "Friendly Euruko" anytime soon.</p>
<p>We're going to take a break. Personally, I want to see if I get the itch to do it again.<br />More importantly, I want to wait until I have the time to do it.<br />I want to feel "bored" again, and think to myself "I have some spare time. What should I do next?"</p>
<p>We will meet at future events for sure!<br />Please come and day "Hi!"<br />I'm genuinely happy when new folks approach me to do that.</p>
<h3 id="heading-outro">Outro</h3>
<p>Friendly has been a transformational event for me. I learned a lot about Ruby, our community, sales and marketing, about what matters to people and how to approach them, but most importantly it helped me create this connection with our community like I could have not be able to do differently.</p>
<p>Thank you Lucian, Jakob, Stefan and Alex for bringing this vision to life.</p>
<p>Thank you sponsors for making this possible.</p>
<p>But most importantly I want to thank our guests for coming and being so warm and friendly.<br />Without <strong>you</strong>, Friendly wouldn't have happened like it did.</p>
<p>I hope we inspired others to go out there and do something outlandish. I hope others will want to organize the conference they would like to visit. I hope we will get other islands like Friendly.</p>
<p>Friendly is going to be heavily imprinted in my memory and caracter forever.</p>
<p>Thank you 🥹</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758278399258/3c5e7c10-d5a3-48f1-a9e6-b8866d1ee76c.jpeg" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Your company's digital brain]]></title><description><![CDATA[What do you need in your digital brain?
That's how I think about Avo now. It's not some closeted admin panel where only five people dare to go because touching the data wrong might crash the app.
It's the place where you invite your whole team to run...]]></description><link>https://blog.adrianthedev.com/your-companys-digital-brain</link><guid isPermaLink="true">https://blog.adrianthedev.com/your-companys-digital-brain</guid><category><![CDATA[INTERNAL TOOL]]></category><category><![CDATA[Rails]]></category><category><![CDATA[Company]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Wed, 09 Jul 2025 10:07:26 GMT</pubDate><content:encoded><![CDATA[<p>What do you need in your digital brain?</p>
<p>That's how I think about Avo now. It's not some closeted admin panel where only five people dare to go because touching the data wrong might crash the app.</p>
<p>It's the place where you invite your whole team to run your operations. Managing plans, subscriptions, users, everything that keeps your business running.</p>
<p>The problem we're solving is the same one Rails solved years ago: stop building the same thing over and over again. Rails doesn't make you build your own view layer, modeling, or database layer because that groundwork is already there, battle-tested by hundreds of thousands of apps.</p>
<p>Same with Avo. We have hundreds of customers running this in production. They've kicked the tires, hit edge cases, found corner cases. We've fixed them. So when you need to build operational software, internal tools, or content management systems, you get all that knowledge baked in.</p>
<p>You'll probably have most of the features you need before you actually need them.</p>
<p>That's the power of building on proven foundations instead of reinventing the wheel every time.</p>
<p>What operational tools are you still building from scratch that you wish someone had already solved?</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtube.com/shorts/rCtA36RJ918">https://youtube.com/shorts/rCtA36RJ918</a></div>
]]></content:encoded></item><item><title><![CDATA[Developer marketing is important]]></title><description><![CDATA[Here's something that's been on my mind lately about the Rails ecosystem.
For the past 10 years, there's been massive investment in dev tooling, especially for JavaScript and TypeScript companies. They take some of that funding and deploy it to marke...]]></description><link>https://blog.adrianthedev.com/developer-marketing-is-important</link><guid isPermaLink="true">https://blog.adrianthedev.com/developer-marketing-is-important</guid><category><![CDATA[Developer]]></category><category><![CDATA[DevRel]]></category><category><![CDATA[marketing]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[Rails]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Wed, 02 Jul 2025 04:00:32 GMT</pubDate><content:encoded><![CDATA[<p>Here's something that's been on my mind lately about the Rails ecosystem.</p>
<p>For the past 10 years, there's been massive investment in dev tooling, especially for JavaScript and TypeScript companies. They take some of that funding and deploy it to marketing. And whether we like it or not, marketing has a huge impact on what technologies developers choose, what stacks they pick, what frameworks they use day-to-day.</p>
<p>Meanwhile, Rails has been quietly building incredible things. But we haven't been as vocal about it.</p>
<p>That's why I'm passionate about Rails events, conferences, and meetups. It's our way of moving the needle in the marketing department. People need to see that Ruby's alive, Rails is alive, things are happening, new features are being released, people are getting together.</p>
<p>I love the "one person framework" narrative, but I'd also love Rails to be the "thousand employee company framework." We need large and medium-sized companies pushing things forward like Shopify is doing.</p>
<p>These events—from large conferences to smaller meetups—this is our marketing push. This is how we show the world that the Rails ecosystem is alive, breathing, and growing.</p>
<p>The technology speaks for itself. Now we just need to make sure people hear about it.</p>
<p>What's your take? Do you think the Rails community is doing ok in the marketing department or it needs to get better at marketing itself?</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtube.com/shorts/hOdlrjod2Ss">https://youtube.com/shorts/hOdlrjod2Ss</a></div>
]]></content:encoded></item><item><title><![CDATA[One of the first medium-sized Hotwire apps]]></title><description><![CDATA[Remember the pandemic when we were all stuck at home? That's when I built the first version of Avo.
It started as a challenge to see if I could do it. A Vue.js frontend with a Rails API backend. Nothing fancy, just me experimenting during lockdown.
T...]]></description><link>https://blog.adrianthedev.com/one-of-the-first-medium-sized-hotwire-apps</link><guid isPermaLink="true">https://blog.adrianthedev.com/one-of-the-first-medium-sized-hotwire-apps</guid><category><![CDATA[hotwire]]></category><category><![CDATA[haters]]></category><category><![CDATA[Twitter]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Tue, 24 Jun 2025 21:00:13 GMT</pubDate><content:encoded><![CDATA[<p>Remember the pandemic when we were all stuck at home? That's when I built the first version of Avo.</p>
<p>It started as a challenge to see if I could do it. A Vue.js frontend with a Rails API backend. Nothing fancy, just me experimenting during lockdown.</p>
<p>Then in December 2020, DHH released Hotwire. And some stranger on Twitter told me he'd never use Avo because it used Vue.js, calling it "the worst thing ever." He said the only thing worth using was Hotwire.</p>
<p>You know what I did? I took a few months off work and rebuilt the entire project from scratch just to prove it could be done.</p>
<p>I was probably one of the first medium-sized projects to use Hotwire from day one. Avo v1 launched in February 2021.</p>
<p>Looking back, that random Twitter comment ended up being one of the best things that happened to the project. Sometimes the harshest feedback pushes you to build something better.</p>
<p>Have you ever had a critic accidentally help you improve your work?</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtube.com/shorts/Ain4kCOaf2Q">https://youtube.com/shorts/Ain4kCOaf2Q</a></div>
]]></content:encoded></item><item><title><![CDATA[RailsConf '25 and the Imposter Syndrome]]></title><description><![CDATA[I'm heading to the last RailsConf's Hack Spaces and honestly, I have massive imposter syndrome.
I'm looking at the other maintainers and seeing Marco Roth, Rosa from Solid Queue, Steven, Jose Valim with Hotwire Combo Box, Chris Oliver. These are the ...]]></description><link>https://blog.adrianthedev.com/railsconf-25-and-the-imposter-syndrome</link><guid isPermaLink="true">https://blog.adrianthedev.com/railsconf-25-and-the-imposter-syndrome</guid><category><![CDATA[railsconf]]></category><category><![CDATA[hackspaces]]></category><category><![CDATA[Rails]]></category><category><![CDATA[Imposter syndrome]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Mon, 23 Jun 2025 11:03:16 GMT</pubDate><content:encoded><![CDATA[<p>I'm heading to the last RailsConf's Hack Spaces and honestly, I have massive imposter syndrome.</p>
<p>I'm looking at the other maintainers and seeing Marco Roth, Rosa from Solid Queue, Steven, Jose Valim with Hotwire Combo Box, Chris Oliver. These are the Rails stars. And then there's me.</p>
<p>But here's the thing about imposter syndrome in our industry: everyone feels it sometimes. Even the people you look up to probably felt the same way at some point.</p>
<p>When people get me talking about code, community, and building SaaS products, I can go for hours. That's my zone. That's where the imposter syndrome melts away because I'm just sharing what I genuinely care about.</p>
<p>I'm excited to connect with people who are building things, solving problems, and pushing Rails forward. Not because I belong in some exclusive club, but because we're all just developers trying to build better software.</p>
<p>If you're at RailsConf in Philly this July and see someone who looks slightly overwhelmed by it all, that's probably me. Come say hi anyway.</p>
<p>Sometimes the best conversations happen when you embrace being the person who doesn't quite feel like they belong yet.</p>
<p>Check out the lineup on the RailsConf website <a target="_blank" href="https://railsconf.org/hack-spaces/#:~:text=Avo,Ruby%20on%20Rails">https://railsconf.org/hack-spaces/#:~:text=Avo,Ruby%20on%20Rails</a></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtube.com/shorts/rlVlmCcqWhM">https://youtube.com/shorts/rlVlmCcqWhM</a></div>
]]></content:encoded></item><item><title><![CDATA[Avo beyond admin panels]]></title><description><![CDATA[I've been marketing Avo as an admin panel framework for years. And it's a very good one, but I think it's time to make the distinction between a "thrown-together" admin panel that nobody really uses (because they're afraid of touching the data or the...]]></description><link>https://blog.adrianthedev.com/avo-beyond-admin-panels</link><guid isPermaLink="true">https://blog.adrianthedev.com/avo-beyond-admin-panels</guid><category><![CDATA[admin panels]]></category><category><![CDATA[INTERNAL TOOL]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Thu, 19 Jun 2025 21:14:04 GMT</pubDate><content:encoded><![CDATA[<p>I've been marketing Avo as an admin panel framework for years. And it's a very good one, but I think it's time to make the distinction between a "thrown-together" admin panel that nobody really uses (because they're afraid of touching the data or they don't have test coverage) and robust, optimized, well-tested, and documented operational software.</p>
<p>I never bashed other solutions. I tried to learn from them. They were built in different times with different technology and probably different goals in mind.</p>
<p>Avo isn't this "glorified database browser" that only does basic CRUD. One thing our users and I noticed right away was that these labels—admin panel, internal tool, content management system, CRM—they all blend into this fully customizable digital brain of your product.</p>
<p>And that's what we're all about: providing the tools you need to build the infrastructure to run your company.</p>
<p>Tools that evolve with you from one person to a few hundred people, like some of our customers have. Tools that are battle-tested by multiple organizations at once. Tools that have the features you need before you need them. Tools that put your mind at ease and enable you to ship the more unique aspects of your app instead of boilerplate.</p>
<p>So I'm curious: where do you draw the line between "admin panel" and "operational software"? What are your pain points with internal tooling right now?</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/shorts/4bau__e6mys">https://www.youtube.com/shorts/4bau__e6mys</a></div>
]]></content:encoded></item><item><title><![CDATA[Two things I wish I knew when I started to build an internal tool framework]]></title><description><![CDATA[There are two things I wish I knew when I started to build an internal tool framework. 🙌 If you do them properly, you'll be on the right track.
People want to get started fast. Fast is the main word here. They have a problem to fix, an idea to share...]]></description><link>https://blog.adrianthedev.com/two-things-i-wish-i-knew-when-i-started-to-build-an-internal-tool-framework</link><guid isPermaLink="true">https://blog.adrianthedev.com/two-things-i-wish-i-knew-when-i-started-to-build-an-internal-tool-framework</guid><category><![CDATA[INTERNAL TOOL]]></category><category><![CDATA[lean]]></category><category><![CDATA[start]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Thu, 15 May 2025 18:31:24 GMT</pubDate><content:encoded><![CDATA[<p>There are two things I wish I knew when I started to build an internal tool framework. 🙌 If you do them properly, you'll be on the right track.</p>
<p>People want to get started fast. Fast is the main word here. They have a problem to fix, an idea to share, or a requirement, and they want to see it done. They don't want to lose momentum. When they lose the momentum, they lose the focus and drive to fix the problem. They might lose interest and might even stop working on the problem.</p>
<p>That's a bad outcome for them (obviously 🙄).</p>
<p>It's kinda like writing. When you start to write something, you don't start with building the editor, designing the font, or cutting down a tree to make paper out of it. You just need to write; to put your ideas there; to get them out of your head.</p>
<p>It's the same with folks trying to build the tools that they need.</p>
<p>They! Just! Need! To! Ship! It! Fast! 🙌</p>
<p>After they've built most of what they needed on the surface, they'll start to dig in and build the nitty-gritty. They'll want to customize something deeper than the basics. That's when you'll want to give them those options. Try to put yourself in their minds and think about what you'd need if it were you building the product.</p>
<p>Can they change the colors, the spacing, the query, the formatting? Great! That means they can carve out the experience they want to give to their users.</p>
<p>This is exactly the way we approach building Avo. We let our users build 70-80-90% of their tooling with incredible ease. We give them great defaults and amazing features that they will eventually use and customize deeply.</p>
<p>Short version: Keep it simple to start with, but make it easy to customize later 🙌</p>
]]></content:encoded></item><item><title><![CDATA[Building admin panels sucks 😡]]></title><description><![CDATA[I've probably built a hundred of them in the past, and I was mostly doing a bad job.
I started seeing similarities from one to another. Common features which, even if they seemed simple to build, I would still make the same mistakes over and over aga...]]></description><link>https://blog.adrianthedev.com/building-admin-panels-sucks</link><guid isPermaLink="true">https://blog.adrianthedev.com/building-admin-panels-sucks</guid><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Thu, 08 May 2025 11:10:36 GMT</pubDate><content:encoded><![CDATA[<p>I've probably built a hundred of them in the past, and I was mostly doing a bad job.</p>
<p>I started seeing similarities from one to another. Common features which, even if they seemed simple to build, I would still make the same mistakes over and over again. It sounds like I have a memory problem or I'm a bad engineer but when I spoke with other developers, they happened to do the same and it wasn't just me</p>
<p>The next thing I did was try to extract tiny bits that I could re-use in multiple projects. That worked out nicely for a while but I ended up with fragmented bits of code that were brittle when put together and had slight variations from project to project.</p>
<p>That's when it hit me 🤯</p>
<p>Internal tools should be built in a cohesive framework that is purposely made for that. We do the same with E-commerce, with Content Management Systems, with Application Tracking Systems, and other pieces of software. We have platforms purposefully built for a specific job.</p>
<p>So why should we cobble together odd libraries, spend precious time, focus, and resources to build the same thing that we built over and over again. We should use those resources to focus on the things that make our app bring that unique value to our customers.</p>
<p>So, Avo was born out of necessity - the framework that makes building internal tools a breeze</p>
<p>If any of this resonated with you, go to <a target="_blank" href="https://avo.cool">https://avo.cool</a> (yes, that's a valid domain name) and give it a try.</p>
]]></content:encoded></item><item><title><![CDATA[Balkan Ruby '25 - The long term]]></title><description><![CDATA[I love traveling! It's a fact. I like traveling to different places and meeting different people. Conferences make that possible and more interesting because the people I will meet will most likely have something in common with me.
Balkan Ruby is one...]]></description><link>https://blog.adrianthedev.com/balkan-ruby-25-the-long-term</link><guid isPermaLink="true">https://blog.adrianthedev.com/balkan-ruby-25-the-long-term</guid><category><![CDATA[Rails]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[conference]]></category><category><![CDATA[community]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Tue, 29 Apr 2025 11:11:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1745924933264/67d58ee4-4741-455d-8358-f05b2e0c668b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I love traveling! It's a fact. I like traveling to different places and meeting different people. Conferences make that possible and more interesting because the people I will meet will most likely have something in common with me.</p>
<p>Balkan Ruby is one of those events where I feel like at home. It might be the proximity to my country and all of that but I have a feeling that the people have something to do with it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745924960166/db433e9e-4e3f-4c1f-bca9-3475dcbc92d8.jpeg" alt class="image--center mx-auto" /></p>
<p>The theme this year was "For the long term" so the talks were about that.</p>
<p>Andrey started the conference with a very great conversation-starter talk about coding with privacy in mind where he outlined how our personal data can be so easily linked together from different sources, so the easiest way to protect the data is to not record it.</p>
<p><a target="_blank" href="https://x.com/realPawelS">Pawel</a> who started building apps "since the last century" showed us that even an "old dog" (sorry Pawel) can learn new tricks.</p>
<p>He openly admitted in front of a bunch of developers that he vibe codes from time to time and he enjoys it. Them proceeded to demo a voice-operated dog that listens to commands. What's that all about?</p>
<p><a target="_blank" href="https://x.com/bbatsov">Bohzidar</a>, after about 10 minutes of jokes and puns spoke about the beginnings of Ruby and how it influenced the whole programming community from Homebrew and Markdown all the way to how modern package managers work. It was quite a crazy story.</p>
<p><a target="_blank" href="https://x.com/yarotheslav">Yaro</a>’s talk was about how AI is influencing our developer lives, about how it can help in the day to day work and most importantly why each one of us should pick it up so we are not left behind.</p>
<p><a target="_blank" href="https://x.com/yukideluxe">Julia</a> had a very nice talk about how they do things at Harvest. She talked about the Rails pre-1 version codebase, the Delta Force team but also about a few "this is the last things, I promise..." 🤨 other ways she improves the codebase and why we leave the codebase better than we found it.</p>
<p><a target="_blank" href="https://x.com/jeremysmithco">Jeremy</a> gave an incredible overview about how he escaped limbo and refactored two of his projects with the utmost precision. Almost made me feel bad about my coding techniques 🫣</p>
<p>There were other great talks that covered mental health, coping, improving and just having a better outlook on the work-life balance.</p>
<p>I really can't recommend it enough that you go and watch the videos when they'll come out.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745924460895/bddfe225-0bbf-4d3d-a91a-18ffb2e5c1f8.jpeg" alt class="image--center mx-auto" /></p>
<p>The theme was "For the long term" but <strong>the</strong> <strong>hallway conversations were around AI</strong>.</p>
<p>"Why, why now, why me, should we, will we, will it" and so much more questions around that.</p>
<p>I loved that the conversations went in both directions ranging from "I'm not using it", or "I don't like it", to "I use Cursor" or "Windsurf is better", all the way to "I really tried vibe coding and I think there's something there."</p>
<p>I gained a lot of perspective on where things stand and where they are going so if you want my take on AI and coding... definitely use it! It's a whole spectrum between "vibe code all the things" to not using it. First use a smart IDE like Cursor and then try a bit of vibe coding to build boring stuff like bash scripts, tedious tasks or even prototypes to get a feel for how the project could look like.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745924494940/67d31d2c-1a67-45c3-a548-70ae58b8e2b0.jpeg" alt class="image--center mx-auto" /></p>
<p>We didn't just attend <a target="_blank" href="https://balkanruby.com/">Balkan Ruby</a>, but we made a whole thing about it.</p>
<p>Me and <a target="_blank" href="https://x.com/paul_ionut_bob">Paul</a> did a few days of in-person retreat, where we spoke about the future of <a target="_blank" href="https://avohq.io/">Avo</a> and did a bit of coding alongside that.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745924478564/380c4183-1a4f-4c9a-9a82-05d270f67b6c.jpeg" alt class="image--center mx-auto" /></p>
<p>We also were in the position to sponsor the drinks 🍻 for the entire conference which was so rewarding.</p>
<p>Balkan quickly became that event where we could go, hang out, make plans, execute, but also connect with the community, make new friends and learn in the process.</p>
<p><a target="_blank" href="https://x.com/gsamokovarov">Genadi</a> and the team did a great job this year too. I hope they continue that for many more years to come so if you're looking for a cool event in the spring, definitely think about visiting Balkan Ruby.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745924502373/0b633120-3bc5-4ba4-b685-96f3b3bdafd3.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745924507236/0e92f184-18a7-4c80-8b95-9d495aaef140.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745924517613/5bdb4e1c-d632-40a9-9ecd-286b8a530ab5.jpeg" alt class="image--center mx-auto" /></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=RhzBiB1GwuA">https://www.youtube.com/watch?v=RhzBiB1GwuA</a></div>
]]></content:encoded></item><item><title><![CDATA[Tropical.rb, an intimate experience that brought the whole LATAM Ruby community together]]></title><description><![CDATA[I'm still in Brazil, but I have that feeling that "it's over". It's that feeling you get after you had the most wonderful time on a getaway with friends, and you forgot the monotony of work and life.
Tropical.rb was a surprise to me. The Brazil Ruby ...]]></description><link>https://blog.adrianthedev.com/tropicalrb-an-intimate-experience-that-brought-the-whole-latam-ruby-community-together</link><guid isPermaLink="true">https://blog.adrianthedev.com/tropicalrb-an-intimate-experience-that-brought-the-whole-latam-ruby-community-together</guid><category><![CDATA[Ruby]]></category><category><![CDATA[Rails]]></category><category><![CDATA[community]]></category><category><![CDATA[conference]]></category><category><![CDATA[LATAM]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Sun, 07 Apr 2024 02:36:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1712457268941/e3be59f9-2590-4427-8ebe-10c9d68601a4.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I'm still in Brazil, but I have that feeling that "it's over". It's that feeling you get after you had the most wonderful time on a getaway with friends, and you forgot the monotony of work and life.</p>
<p>Tropical.rb was a surprise to me. The Brazil Ruby community was surprise too! They are more than welcoming; they go out of their way to make you feel at home.</p>
<p>So many friendly people came together to celebrate Rails at LATAM's largest Rails conference, and what a celebration it was!</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/1GCdFOhznMo">https://youtu.be/1GCdFOhznMo</a></div>
<p> </p>
<h3 id="heading-the-talks">The talks</h3>
<p>The best speakers you can think of came together to share their experiences with the audience.<br />The talks were about all that's trendy and relevant now and probably some things that we'll hear about in the future. We've had talks that eloquently taught and reminded folks about how to write clean code and refactor technical debt, talks about how to give back to the community and keep Rails going for 100 years from now, but also about internationalization, semantic search, async Rails, and red-black trees (whatever those are). Hotwire and Turbo Native had their spotlight on the stage, as did WASM, Kamal, Thruster, and Propshaft.<br />I felt a bit out of place with my "How to build a business on Rails and Open-Source" talk, but the reactions and conversations I had afterward confirmed my suspicion that more and more Rails developers want to break out of the nine-to-five job and try something new.</p>
<p>We also had a great AMA session hosted by Robbie Russel with Amanda and Bruno Miranda. So many valuable ideas came out of that conversation that I would suggest everyone watch when it comes out.</p>
<h3 id="heading-organization">Organization</h3>
<p>The organizers did a splendid job of ensuring everyone had a good time. You could see the smiles on everyone's faces. They had surprises for the attendees, one after another.<br />Even if we didn't stick to the schedule, no part of it felt rushed. We all wanted to be in it and enjoyed the experience.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456882848/fac61e8a-4256-4391-bc7e-c225bb4f13ce.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712457301280/aa80cf38-b41a-41e7-87c8-80abd12078ec.jpeg" alt class="image--center mx-auto" /></p>
<h3 id="heading-i-made-friends">I made friends</h3>
<p>On a personal note, I made friends. So many new and close friends. Close to my heart but far geographically.<br />But it's okay; I have a hunch that we'll see each other again and relive all that we felt in São Paulo.</p>
<p>I also met many online friends from Twitter and Discord in person, many of whom were with me on my journey with Avo.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456713010/cbd2a628-7256-4b45-a999-e5001115346e.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456727485/4bd875b5-7c8e-4e68-ac13-8034d7ab21df.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456752442/1f7f5a4e-ea3a-4e3e-871c-28556b32f83e.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456736661/ba455749-72be-4a34-8ba5-2011eb865080.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712458310986/3e1cb8e5-c883-4dde-add4-7eb82faeed79.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456724197/242c0ef5-aa9a-4e9a-b5dd-69b6feed6da8.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456752436/418b740b-397e-4b7b-b1a8-d38c3c94cf59.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456731849/2da2b0f6-5835-4ddb-8d8a-00cadc0adc8a.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456721006/c7e7b55b-a85e-4da4-9929-6d102eba6026.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712458329545/844cd005-a0b5-430a-a1c4-fbc1f33206e3.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712456764376/4483c33b-76cf-40d2-ba54-d56918fad376.jpeg" alt class="image--center mx-auto" /></p>
<h3 id="heading-thank-you">Thank you!</h3>
<p>Thank you, Cirdes, Débora, Juliana, and Rafael, for hosting this incredible celebration of Rails. I know it was scary and risky to bring back Tropical. rb after all these years, but it was all worth it!<br />Good job!</p>
<p>But I want to thank the wonderful Ruby community in Brazil and LATAM, which made me feel like I was home when I was so far away.</p>
<p>This community rocks!</p>
<p>PS: You can follow my "live-tweet" session <a target="_blank" href="https://twitter.com/adrianthedev/status/1776597428470243660">here</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Hosting Ruby meetups with non-Ruby developers rules!]]></title><description><![CDATA[Last evening, we had our first on-the-road Ruby meetup in Sibiu.
We didn't have too many expectations as we knew that the Ruby scene in Sibiu is not that hot.
Luckily, our friend Stefan runs Sibiu Web Meetup and has been running it for about 5 years ...]]></description><link>https://blog.adrianthedev.com/hosting-ruby-meetups-with-non-ruby-developers-rules</link><guid isPermaLink="true">https://blog.adrianthedev.com/hosting-ruby-meetups-with-non-ruby-developers-rules</guid><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Mon, 05 Feb 2024 10:43:18 GMT</pubDate><content:encoded><![CDATA[<p>Last evening, we had our first on-the-road <a target="_blank" href="https://www.meetup.com/ruby-romania/events/298491370/">Ruby meetup in Sibiu</a>.</p>
<p>We didn't have too many expectations as we knew that the Ruby scene in Sibiu is not that hot.</p>
<p>Luckily, our friend <a target="_blank" href="https://twitter.com/stefanbc">Stefan</a> runs <a target="_blank" href="https://www.linkedin.com/showcase/sibiuwebmeetup/">Sibiu Web Meetup</a> and has been running it for about 5 years now. We also found a partner in <a target="_blank" href="https://sibiu-it.ro">Sibiu IT Cluster</a>, an organization that supports the whole IT&amp;C sector in that region.</p>
<p>They both sent out in their network that we're hosting our <a target="_blank" href="https://www.meetup.com/ruby-romania/">Ruby Meetup</a>.</p>
<p>We had two talks prepared. I had my "We're living in a Rails Renaissance" talk ready which was made to pump up Rails developers and to highlight the new developments around Rails.</p>
<p>I talk about how Rails got started, about the foundation, Rails World, finishing up with Rails 8, and all the cool new things we have got lately or will get soon.</p>
<p>Calin, from Agile Freaks, had a Rails at Scale presentation where he spoke about a few big public projects at scale and a few of his.</p>
<p>Six o'clock comes, and we start greeting our guests. We had about 20-25 people RSVPing on <a target="_blank" href="http://meetup.com">meetup.com</a>, so we were expecting 20 max.</p>
<p>Then, people wouldn't stop coming in. We filled the auditorium to about 30 something ish folks from all age groups. We were astounded but glad at the same time.</p>
<p><a target="_blank" href="https://twitter.com/_alexmarinescu">Alex</a> kicks off the evening, and then I take the stage in my bright red <a target="_blank" href="https://rubyonrails.org/world">Rails World</a> t-shirt.</p>
<p>I start by asking about who's a developer, who does Ruby in the day-to-day life, and who has used Ruby ever.</p>
<p>Of the 35 people there, only about 8-10 said they used Ruby before.</p>
<p>Oops... my presentation is going to be received differently. I start to wing it and apply a different spin to different chapters.</p>
<p>I wasn't prepared to have so many newbies.</p>
<p>But it all goes fine, and after about 20 minutes, I conclude with something along the lines that Rails was born from simplicity and productivity, and with this new no-build paradigm, fewer dependencies, and owning the full stack, we are still going in that direction.</p>
<p>The Q&amp;A is next.</p>
<p>People started asking many questions about Ruby and Rails that I didn't expect: "Does it have a big docker setup for local development?". It does, I say, and I continue to tell them that you don't need that. You run one command, and you have the whole server up.</p>
<p>"Does it have an ORM?". It does, I say, and I continue to tell them how amazing it is.</p>
<p>"What's the learning curve?". And I tell them the little talk I had before taking the stage about how someone who did Java had a look over Ruby before the meetup and can't fathom why we don't have more verbosity and how we can write programs with so few words.</p>
<p>Then we go into this cool talk where I tell them about how convention over configuration enables ten different developers to come to an existing app and know where everything is, which rarely happens in other ecosystems.</p>
<p>It was one of the most rewarding Q&amp;A sessions I ever had. I could see that people wanted to learn more.</p>
<p>After the talks, we had this magical moment where young college students were trying to find us and ask all sorts of cool questions; after we gave the answers, they were like, "Oh really? That's so cool".</p>
<p>On one corner, there was Jakob telling people about the magic of generators and how much value you get from running one command, in another, there was Lucian going in deep about how cool Ruby meta-programming is, Alex was doing his part, telling them about date helpers and even Paul started to preach the word about how Ruby was the coolest thing he ever learned.</p>
<p>In a different corner, I talked about how easy it is to create full products and businesses on Rails and what a cool platform the web is.</p>
<p>We were surprised. Surprised that this, a meetup that had the potential to be very small and a flop, became the greatest experience where we got quite a few people curious to give Ruby a try. Rails too.</p>
<p>Now, there are probably 10 or 12 students who are scouring the docs website looking for tutorials and getting hungry to see what cool things they can build with Rails.</p>
<p><a target="_blank" href="https://www.youtube.com/watch?v=_zvR8y03N5s">Video link</a></p>
]]></content:encoded></item><item><title><![CDATA[The 2023 Ruby Conference season is (almost) over]]></title><description><![CDATA[I call it a Conference season because we just had 6 Ruby conferences in four consecutive weeks on three continents. And that's wild!
This is just a testament to how vibrant and healthy the Ruby community really is.
The conferences
Wroclove.rb started...]]></description><link>https://blog.adrianthedev.com/the-2023-ruby-conference-season-is-almost-over</link><guid isPermaLink="true">https://blog.adrianthedev.com/the-2023-ruby-conference-season-is-almost-over</guid><category><![CDATA[Ruby]]></category><category><![CDATA[Rails]]></category><category><![CDATA[community]]></category><category><![CDATA[conference]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Sun, 08 Oct 2023 09:27:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1696757169599/4cbc10b2-dfa2-4786-acb7-c160e68ea9c1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I call it a Conference season because we just had 6 Ruby conferences in four consecutive weeks on three continents. And that's wild!</p>
<p>This is just a testament to how vibrant and healthy the Ruby community really is.</p>
<h3 id="heading-the-conferences">The conferences</h3>
<p><a target="_blank" href="https://wrocloverb.com/">Wroclove.rb</a> started the season on September 15th in the beautiful city of Wroclaw, Poland.</p>
<p><a target="_blank" href="https://2023.euruko.org/">Euruko 2023</a> happened between 21-23 September in Vilnius, Lithuania.</p>
<p><a target="_blank" href="https://friendlyrb.com/">Friendly.rb</a> was next on the 27th and 28th of September in Bucharest, Romania.</p>
<p><a target="_blank" href="http://railsworld.com/">Rails World</a> happened on October 5-6 in Amsterdam.</p>
<p><a target="_blank" href="https://rockymtnruby.dev/">Rocky Mountain Ruby</a> happened at the same time on October 5-6 in Boulder, Colorado.</p>
<p><a target="_blank" href="https://rubyconfth.com/">Ruby Conf Thailand</a> quickly followed on October 6-7 in Bangkok, Thailand.</p>
<h2 id="heading-the-triathlon">The Triathlon</h2>
<p>I was able to attend Euruko, Friendly.rb, and Rails World, alongside 8 other cool folks. We jokingly named ourselves "The Triathlon Nine". It's silly, I know, but we did it anyway.</p>
<h3 id="heading-euruko">Euruko</h3>
<p>I was in contact with Ali and Sergy for most of the past year and I know how many hurdles they had to overcome to make this event a reality.</p>
<p>Euruko is a traveling event organized annually, every year in a different European city chosen by the participants. It has a legacy from 2003 and it has to be just right.<br />I think they did it right.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696756753250/28298f1a-f32e-4b9a-9406-a03202fc689c.jpeg" alt class="image--center mx-auto" /></p>
<p>The venue was pretty cool, the Technical University of Vilnius. It was mainly one large track with a secondary stage for sponsors, and others that wanted to present their work.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696756828252/5b5f1fd3-b9b3-49c4-a644-da7e8b3455c8.jpeg" alt class="image--center mx-auto" /></p>
<p>This year's edition also introduced an unconf format where participants submitted talks and then voted on who they wanted to see on stage. I was super happy to get the chance to talk a little bit about internal tools, and Avo.</p>
<p>The talks were pretty varied with guests from all over the globe.</p>
<p>Another cool surprise was a talk from <a target="_blank" href="https://en.wikipedia.org/wiki/Yukihiro_Matsumoto">Matz</a> delivered through video and a live discussion panel, live from Japan.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696756855363/c5304aef-53da-4605-b6cf-7e5e6970d339.jpeg" alt class="image--center mx-auto" /></p>
<p>After the first day, we had a train waiting for us at the train station to take us to a nice brewery where we partied, courtesy of Appsignal. You heard that right. A train full of Ruby developers (on rails)... pun intended.</p>
<p>I met many cool folks and put some faces to those Twitter profiles.</p>
<h3 id="heading-friendlyrb">Friendly.rb</h3>
<p>This is very dear to my heart because I am one of the hosts. I and my co-hosts worked for the better part of the last year to ensure this first edition is going to be memorable.<br />We knew that all eyes were on us.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696756906492/55f89fb7-4e9a-4695-9f8c-4a3c09ab4f48.jpeg" alt class="image--center mx-auto" /></p>
<p>The venue was incredible. Apollo 111 is an independent theatre with an adjacent bar. Just perfect for what we needed. Located in the heart of the city close to many food places and the Old Town.</p>
<p><img src alt class="image--center mx-auto" /></p>
<p>The photo and video crew are professionals. I chose them because they do events much bigger than Friendly.rb. I wanted to ensure that the quality of the deliverables was top-notch.<br />The photos are available on <a target="_blank" href="https://www.flickr.com/photos/friendlyrb/albums">Flickr</a>, and the videos are coming soon.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696756937111/f443d6b6-7500-466d-b7ec-40730c23718d.jpeg" alt class="image--center mx-auto" /></p>
<p>The line-up was sublime! We managed to do what we wanted and have famous speakers and bring newcomers to the stage. Xavier Noria, Elena Tanasoiu, Jeremy Smith, Jason Swett, Nick Sutterer, Tom de Bruijn, and Ayush Newatia were gracious enough to accept the invitation to speak.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696756944801/4f698654-97e0-45be-808b-f7e00188a3b6.jpeg" alt class="image--center mx-auto" /></p>
<p>The talks were various from Ruby, to general tech, to non-tech, mental health, and even a cool talk from Julian Cheal where he did a live-coding session producing music on stage.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696756954745/42049569-687a-4c5e-93e3-bf67899c8752.jpeg" alt class="image--center mx-auto" /></p>
<p>The attendees had plenty of break time to talk and create connections which is the most important thing we wanted to achieve.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696756964010/fbf232e4-b2b0-4bb0-91be-4df94dfbcc16.jpeg" alt class="image--center mx-auto" /></p>
<h3 id="heading-rails-world">Rails World</h3>
<p>Rails World was more of a festival than a conference. Amanda and the organizers went all out. The venue was stunning! The swag was great, the sponsor booths were nicely designed, but most importantly the attendees were very passionate about Rails.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696757035775/221e5c8a-1b79-4e00-86c9-ebdfd3b2c08e.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696756990292/273f52f5-78eb-467c-98b1-a0e1c09a73eb.jpeg" alt class="image--center mx-auto" /></p>
<p>If there were such a thing as "The Oscars" for Rails, then Rails World would have been it.</p>
<p>There were many famous folks from the Rails community and most of the Rails core team was there.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696757043070/046a0b75-19f7-48f6-896c-773eb021afc1.jpeg" alt class="image--center mx-auto" /></p>
<p>The conference started with DHH's keynote where he spoke a little bit about the past and the future. He showed a sneak peek of Turbo 8, Strada, Kamal, and a few other things.</p>
<p>Next came a good round of talks going a little more in-depth with all of the new goodies coming soon. I personally can't wait for the new morphing feature coming to Turbo 8.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696757090528/0bab4334-544a-4cbb-989d-3599744a8689.jpeg" alt class="image--center mx-auto" /></p>
<p>My buddies Yaro and Marco also took the stage to speak about the future of Hotwire, show off some tools, and a few cool techniques.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696757098563/5dbb13f6-4c85-4595-af7e-3e843c76c271.jpeg" alt class="image--center mx-auto" /></p>
<p>There weren't many after-party activities planned by the organizers but Amsterdam has plenty to offer. Somehow... most of us ended up at the Beer Temple. If you were there, you know what I'm talking about.</p>
<h3 id="heading-next-up">Next up</h3>
<p>I'm still looking forward to <a target="_blank" href="https://helvetic-ruby.ch/">Helvetic.rb</a> on November 24th to properly close off the Ruby Conference season.</p>
<p>This has been an amazing year with many travels on my part. I met wonderful folks and made new friends which I will miss until next year.</p>
<p>One thing is for sure. The Ruby and Rails community is not dying, but witnessing a renaissance with new tooling, new events, and new talent.</p>
]]></content:encoded></item><item><title><![CDATA[My first Brighton Ruby]]></title><description><![CDATA[I’m on the train towards London. I still need to decompress from everything that happened in the past two days. I hope it doesn’t sound harsh when I say “to decompress”, but it does feel like I experienced so many things and met so many cool folks in...]]></description><link>https://blog.adrianthedev.com/my-first-brighton-ruby</link><guid isPermaLink="true">https://blog.adrianthedev.com/my-first-brighton-ruby</guid><category><![CDATA[Ruby]]></category><category><![CDATA[conference]]></category><category><![CDATA[community]]></category><category><![CDATA[friends]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Sun, 02 Jul 2023 09:33:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/eKcYTT9mgMI/upload/9cf9f18df4b5e4f6f52d3b5f4997b754.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I’m on the train towards London. I still need to decompress from everything that happened in the past two days. I hope it doesn’t sound harsh when I say “to decompress”, but it does feel like I experienced so many things and met so many cool folks in such a tiny period of time.</p>
<p>But let’s rewind for a sec. It’s June 3rd, and I just returned from Rails Saas in Athens. We had three amazing days of talks, tavernas, and island hopping, all with meeting new folks. I’m saying meeting new folks, but what I really mean is putting a face on people that I already knew from Twitter or GitHub. Folks like <a target="_blank" href="https://twitter.com/marcorth_">Marco Roth</a>, <a target="_blank" href="https://twitter.com/julian_rubisch">Julian Rubisch</a>, <a target="_blank" href="https://twitter.com/kaspth">Kasper</a> and more. I’m not going to go too much into how that conference was and will leave <a target="_blank" href="https://cannycode.io/rails-saas-conf-wrapup/">Peter’s article</a>, which sums it up really cool.</p>
<p>So it’s still June 3rd; I’m at home, decompressing, and remembering the good times, and the thought that pops into my head is, “I want to do this more”. <a target="_blank" href="https://friendlyrb.com">Friendly.rb</a> and <a target="_blank" href="https://rubyonrails.org/world">Rails World</a> are pretty far away in the fall, so the next best thing is Brighton Ruby. I didn’t know too much about <a target="_blank" href="https://brightonruby.com/">Brighton Ruby</a> other than it’s organized by <a target="_blank" href="https://twitter.com/andycroll">Andy</a>, which is all the branding you need. I feel that everything he does, he does it with style and showmanship. So I got into some negotiation with <a target="_blank" href="https://twitter.com/RalucaCostil">my wife</a>, which is the real superhero in this story, for taking care of our 8-month-old while I’m off; but she’s amazing, said, “of course, go for it!” and I got the tickets and made arrangements.</p>
<h3 id="heading-brighton-ruby">Brighton Ruby</h3>
<p>Going to a conference alone might be daunting if you’re an introvert, but I knew I wasn’t alone. I knew Andy, and I was sure he would shake my hand if I bumped into him, so yeah… I know one person there.</p>
<p>I started the day by walking to the Brighton Dome, which is an incredible venue for a conference. The city is as British as you can imagine, with beautiful low buildings and delightful tiny streets.</p>
<p>I got in, registered, and quickly saw many familiar faces. Some I knew in person, and some just from online. Of course, I bumped into Andy, but he didn’t shake my hand but gave me a very heartwarming hug which really uplifted my spirit and confidence.</p>
<h3 id="heading-the-talks">The talks</h3>
<p>The day started with the classic Andy welcoming, introduction and the history of the conference, and pointing out that this is a space where all should feel safe and welcomed. I can't express how important it is that the organizer mentions that and sets the tone of it.</p>
<p>Eileen started the day with her incredible talk about the Magic of Rails. I’m saying incredible because she touched on a few key aspects, like why the Rails internals are sometimes complex just so we can benefit from the best public APIs we can have, how all Rails’ gems fit together, how they are initialized, and how we should hook in and extend it, and about how the core team is organized and how they work on it. I truly feel that this talk should be seen by all Rails developers at some point of their careers. It explains so many things.</p>
<p><a target="_blank" href="https://twitter.com/schwad_rb">Schwad</a> was next with his <s>Brighten Ruby</s> ”Scarpe diem” talk, where he so delightfully demoed Scarpe, built a fake virus for grandmas, and made all of us talk about it on the breaks.</p>
<p><a target="_blank" href="https://krtierney.com/">Kaitlyn Tierney</a> gave one of my favorite talks of the day on a subject that is very close to me. The librarian’s guide to documentation. So many good tips there about writing, maintaining, and pushing your team to create documentation for public or private products. If you ever see her in a lineup at a conference, go see her.</p>
<p><a target="_blank" href="https://twitter.com/codefolio">Noah Gibbs</a> was next with his incredibly cool hand-drawn slides about “When not to use Rails”. This talk also hit hard with me because I am also in the “right tool for the right job” camp. This wasn’t just a theoretical talk but had actionable bullet points about when to use it or not, and what to worry and not worry about.</p>
<p>After a quick break, the lighting talks started with a cool presentation about how Ruby evolved in 20 years which will put things into perspective, a quick lesson into what "Job Smearing" is, Five things <a target="_blank" href="https://twitter.com/hanaharencar">Hana</a> loves about Ruby, The front-end and UX, and a quick demo into how to write a Rubocop rule.</p>
<p>One of the most impressive and courageous talks was displayed by <a target="_blank" href="https://twitter.com/timriley">Tim Riley</a>, with singing, dancing, and presenting the history of Ricky Martin and his song “Livin’ la vida <s>Hanami</s> Loca”. This wasn’t just a “Here’s Hanami, and here’s how to use it” talk, but a very lean and organized introduction into why, and how other frameworks do it and that it’s not a competition. We’re seeing that pattern again of using the right tool for the job. Nice one, Tim! I heard many folks speaking about how they just wanted to go back to their hotel and write Hanami for an hour or two.</p>
<p>We had a quick Ice cream break, and Nadia Odunayo came to the stage to tell us about her Ruby mystery story, “The case of the vanished variable”. This wasn’t a presentation, but a funny modern tale that we all needed at that point in the day.</p>
<p>The day was wrapped up by <a target="_blank" href="https://twitter.com/joehart">Joe Hart</a>, who told us about how he likes to spend his time going to conferences and creating Massive Local Multiplayer Games that he can play with the entire audience. We played Super Ruby Bros using our cheers, debugged some code live, and a cool game of Pac-Man together which ended up in a crackle of laughs when someone in the audience exploited the game live. No code was harmed during that talk.</p>
<p>You can see more of the talks in <a target="_blank" href="https://twitter.com/adrianthedev/status/1674805337159786497">my attempt at live-tweeting from the event</a>.</p>
<p>It’s worth mentioning that Brighton Ruby is a conference full of showmanship. If you’ve ever seen Andy, you know what I’m talking about. All speakers really put on a show, not just come there with some slides and start talking. It’s something that all conferences need.</p>
<h3 id="heading-the-socializing">The socializing</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1688289995815/325671eb-95ef-48b4-9b45-58cef68326b8.jpeg" alt class="image--center mx-auto" /></p>
<p>We had a quick socializing session at the venue that turned into breaking out into groups and taking to the streets of Brighton to find a place to have dinner and a drink.</p>
<p>That’s the time at the conference when you should find the folks that are by themselves, take them into your group, and go have fun.</p>
<p>This is when friendships are made. I spent most of the evening having good times with <a target="_blank" href="https://twitter.com/juliancheal">Julian</a>, <a target="_blank" href="https://twitter.com/marioschuettel">Mario</a>, <a target="_blank" href="https://twitter.com/coorasse">Alessandro</a>, <a target="_blank" href="https://twitter.com/marcorth_">Marco</a>, and <a target="_blank" href="https://twitter.com/alexanderadam__">Alex</a>, and ended up closing our last bar for the night with <a target="_blank" href="https://twitter.com/Benoit_Tgt">Benoit</a> and Stan Lo.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1688290007473/e503dc16-78df-4094-9eb8-9fc2a26dae96.jpeg" alt class="image--center mx-auto" /></p>
<p>On the second day, <a target="_blank" href="https://twitter.com/jot">Jonathan</a> was very kind to invite us to a SaaS founders meetup at <a target="_blank" href="https://theskiff.org/">the Skiff</a>, the coolest co-working space in Brighton. I got plenty of good advice from him and the other founders there.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1688290022966/4d6306c2-1097-433b-ab05-50b618aadac9.jpeg" alt class="image--center mx-auto" /></p>
<p>We then went to have lunch, went antique hunting, checked out the pier, and just lost ourselves in the wonderful city of Brighton.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1688290051850/d1215b16-b0a6-4071-9b6b-dc5ca3772edd.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1688290217883/2bd4511f-8834-4b73-b815-e0624fc91b55.jpeg" alt class="image--center mx-auto" /></p>
<p>Of course that after our Tonkotsu ramen dinner, we ended up in a bar where we talked about indie businesses, open-source, and product development, and did a bit of bikeshedding; developers being developers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1688290239722/67dd9f55-cd7d-4280-bba2-517311a8e7a4.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1688290261471/3aa3e1f3-cad1-4c66-bc19-1c3dd8f3fd90.jpeg" alt class="image--center mx-auto" /></p>
<h3 id="heading-closing-thoughts">Closing thoughts</h3>
<p>Overall, a fantastic event, with great people, in a very beautiful city. Brighton Ruby is an inspiration and should be on every person's list at least once. See you there next year!</p>
<p>—</p>
<p>If you enjoy conferences and can’t wait until next year, we're hosting <a target="_blank" href="https://friendlyrb.com/">Friendly.rb</a>, a cozy, boutique, Ruby conference in Bucharest, Romania, in September.</p>
]]></content:encoded></item><item><title><![CDATA[How to bundle assets in a Rails engine]]></title><description><![CDATA[During Rails' lifetime, we had a lot of ways to load, parse, and process assets. The "recommended" way is to hook into the asset pipeline (whichever that is) and, on deployment, let the assets:precompile task to take over and... compile them so they ...]]></description><link>https://blog.adrianthedev.com/how-to-bundle-assets-in-a-rails-engine</link><guid isPermaLink="true">https://blog.adrianthedev.com/how-to-bundle-assets-in-a-rails-engine</guid><category><![CDATA[rails-engines]]></category><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[Rails]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Tue, 10 Jan 2023 19:02:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1673377291416/3b46610f-a995-4152-b009-9659033dd097.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>During Rails' lifetime, we had a lot of ways to load, parse, and process assets. The "recommended" way is to hook into the asset pipeline (whichever that is) and, on deployment, let the <code>assets:precompile</code> task to take over and... compile them so they can be used in your app.</p>
<p>But, if you built an engine that you want to distribute to others, there might be a few things that might get in the way.</p>
<h3 id="heading-asset-pipeline-cons">Asset pipeline cons</h3>
<p>Let's say you're using <code>jsbundling-rails</code> and/or <code>tailwindcss-rails</code> with your distributable engine. To you, it's common to have all you need to compile those assets. You'll have Node.js and all other external dependencies installed and ready to compile everything together, but the parent app that's using your gem might not. They might use <code>importmaps,</code> and they might not have all that Node.js infrastructure.</p>
<p>When the user pushes the Rails app with your gem installed, they might get the gem without any assets (because they haven't been built yet), or they might even get a crash that sprockets (or propshaft) can't find those assets.</p>
<p>But there's a better way!</p>
<h2 id="heading-compile-assets-on-publish-time">Compile assets on publish-time</h2>
<p>One approach we had with <a target="_blank" href="https://github.com/avo-hq/avo">avo-hq/avo</a> was to precompile the assets before we publish a new version and serve them as static assets to the parent app.</p>
<h3 id="heading-how-do-we-do-that">How do we do that?</h3>
<p>The overview is this:</p>
<ol>
<li><p>Set up build commands</p>
</li>
<li><p>Provide a way for the parent app to reach those assets</p>
</li>
<li><p>Run all the compilation commands</p>
</li>
<li><p>Package the gem up with those static assets</p>
</li>
</ol>
<h2 id="heading-1-set-up-build-commands">1. Set up build commands</h2>
<p>You first install your asset handlers as you need them for your project. They can be anything from <a target="_blank" href="https://github.com/rails/jsbundling-rails">rails/jsbundling-rails</a> and <a target="_blank" href="https://github.com/rails/tailwindcss-rails">rails/tailwindcss-rails</a> to webpacker or something custom.</p>
<p>Add some commands to build up those assets. We have the following scripts inside the <code>package.json</code> file:</p>
<pre><code class="lang-json">  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-attr">"prod:build:js"</span>: <span class="hljs-string">"esbuild app/javascript/*.js --bundle --sourcemap --minify --outdir=public/avo-assets"</span>,
    <span class="hljs-attr">"prod:build:css"</span>: <span class="hljs-string">"tailwindcss -i ./app/assets/stylesheets/avo.base.css -o ./public/avo-assets/avo.base.css --postcss"</span>,
  }
</code></pre>
<p>They take the source JS and CSS files, compile them, and move them to a <code>public/assets</code> directory.</p>
<h2 id="heading-2-provide-a-way-for-the-parent-app-to-reach-those-assets">2. Provide a way for the parent app to reach those assets</h2>
<p>When you ship your gem, that <code>public</code> directory will not be public at all. It will be hosted somewhere hidden on that machine, so the browser will not have a way to reach them.</p>
<p>Let's use a <code>Rack::Static</code> middleware to the <code>engine.rb</code> file.</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">module</span> <span class="hljs-title">Avo</span></span>
  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Engine</span> &lt; ::<span class="hljs-title">Rails::Engine</span></span>
    config.app_middleware.use(
      Rack::Static,
      <span class="hljs-symbol">urls:</span> [<span class="hljs-string">"/avo-assets"</span>],
      <span class="hljs-symbol">root:</span> Avo::Engine.root.join(<span class="hljs-string">"public"</span>)
    )
  <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>Now, the parent app will re-route all the traffic from <code>/avo-assets</code> to that "hidden" directory where our compiled assets are.</p>
<h2 id="heading-3-run-all-the-compilation-commands">3. Run all the compilation commands</h2>
<p>When we're ready to ship our gem to RubyGems (or any other gems server), we should run the compilation commands to ensure all the JS and CSS files are compiled, minified, and packaged up how we need them to be in production.</p>
<pre><code class="lang-bash">$ yarn prod:build:js
$ yarn prod:build:css
</code></pre>
<h2 id="heading-4-package-the-gem-up-with-those-static-assets">4. Package the gem up with those static assets</h2>
<p>We need to instruct the <code>gem</code> utility to add the compiled files to the packaged gem.</p>
<pre><code class="lang-ruby">Gem::Specification.new <span class="hljs-keyword">do</span> <span class="hljs-params">|spec|</span>
  spec.name = <span class="hljs-string">"avo"</span>
  spec.version = Avo::VERSION
  <span class="hljs-comment"># more spec properties</span>

  spec.files = Dir[<span class="hljs-string">"{bin,app,config,db,lib,public}/**/*"</span>, <span class="hljs-string">"MIT-LICENSE"</span>, <span class="hljs-string">"Rakefile"</span>, <span class="hljs-string">"README.md"</span>, <span class="hljs-string">"avo.gemspec"</span>, <span class="hljs-string">"Gemfile"</span>, <span class="hljs-string">"Gemfile.lock"</span>]

  spec.add_dependency <span class="hljs-string">"activerecord"</span>, <span class="hljs-string">"&gt;= 6.0"</span>
  <span class="hljs-comment"># other dependencies here</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>The <code>spec.files</code> property knows which files should be bundled up. Finally, you'll see the <code>Dir["{public}/**/*"]</code> will add the whole <code>public</code> directory to the gem, including the <code>avo-assets</code> one.</p>
<p>Run <code>bundle exec rails build</code> to package everything up and profit 🙌</p>
<h3 id="heading-all-you-need-to-know-about-rails-engines">All you need to know about Rails engines</h3>
<p>This post is part of a series I'm writing to share some of my learnings while building my own distributed engine, Avo.</p>
<p><a target="_blank" href="https://avohq.io/rails-engines">All you need to know about Rails Engines</a></p>
]]></content:encoded></item><item><title><![CDATA[Launch that bottom drawer project]]></title><description><![CDATA[If you have a never-launched product in the bottom drawer that you just think, "it's a failed project", I'm here to tell you that it didn't fail yet.
If you didn't launch it, you made it fail! You never gave it a chance!
Give yourself an hour to put ...]]></description><link>https://blog.adrianthedev.com/launch-that-bottom-drawer-project</link><guid isPermaLink="true">https://blog.adrianthedev.com/launch-that-bottom-drawer-project</guid><category><![CDATA[indiedev]]></category><category><![CDATA[launch]]></category><category><![CDATA[projects]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Wed, 30 Nov 2022 10:43:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/xaomtgqTnfU/upload/v1669807146005/RzJF3lD88.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you have a never-launched product in the bottom drawer that you just think, "it's a failed project", I'm here to tell you that it didn't fail yet.</p>
<p>If you didn't launch it, you made it fail! You never gave it a chance!</p>
<p>Give yourself an hour to put it online, post it in a few relevant communities, and get some quick feedback.</p>
<p>That's it! One hour, not the whole glorious vision of the perfect product that you have in your mind.</p>
<p>Depending on the product, here are a few places where you can post it:</p>
<p>➡️reddit<br />➡️Twitter<br />➡️Twitter communities<br />➡️GitHub awesome lists<br />➡️LinkedIn<br />➡️Schedule a quick product hunt<br />➡️Discord servers<br />➡️maybe Quora<br />➡️think about adjacent industries and where those users hang out<br />➡️retweet this article with your product launch</p>
<p>In the following weeks, monitor those posts, and the feedback coming in and draw some conclusions. You'll probably get a lot of "this is not useful" feedback. Try to get in touch with those people and ask why they gave that feedback. You'll learn a lot about the industry/niche you're trying to enter and whether it's worthwhile to keep working on the project.</p>
<p>Two things can happen:</p>
<ol>
<li><p>You end up with good feedback to continue the work and turn it from a project to a product</p>
</li>
<li><p>You'll shut it down and still feel good about making, launching, and showing it to the world</p>
</li>
</ol>
<p>These are both successful outcomes. Keeping it in the bottom drawer is not.</p>
<p>Go and put your product out there 🚀</p>
<hr />
<p>If you like indie dev content, follow me on Twitter at [@adrianthedev](<a target="_blank" href="https://twitter.com/adrianthedev">https://twitter.com/adrianthedev</a>)</p>
]]></content:encoded></item><item><title><![CDATA[Why Successful Startups Use MVPs]]></title><description><![CDATA[Website building platforms like WordPress or Wix undeniably revolutionized the internet.
Why? For the same reason, a band like Green Day draws a festival-sized crowd in comparison to a jazz ensemble formed of professional musicians who studied music ...]]></description><link>https://blog.adrianthedev.com/why-successful-startups-use-mvps</link><guid isPermaLink="true">https://blog.adrianthedev.com/why-successful-startups-use-mvps</guid><category><![CDATA[mvp]]></category><category><![CDATA[Startups]]></category><category><![CDATA[Ruby on Rails]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Wed, 13 Jul 2022 11:31:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1657711793058/XObmw3qkY.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Website building platforms like WordPress or Wix undeniably revolutionized the internet.</p>
<p>Why? For the same reason, a band like Green Day draws a festival-sized crowd in comparison to a jazz ensemble formed of professional musicians who studied music theory their entire lives. It is more easily accessible to the masses.</p>
<p>As long as the majority of people can understand the inner workings of a certain process - spanning from relating to the 3 chords an artist plays in front of them to build their own minimalistic website - they will be drawn to what they can achieve on their own. Relying on an expert in any field of work implies a bigger budget and a schedule you don't always call the shots for.</p>
<p>In the world of companies, a startup is the equivalent of an individual that starts something from scratch. They will need a lot of resources to evolve and they should seek any support they can get. The biggest support always comes in the form of cost- and time-efficient solutions for a business. This is the category an MVP falls under.</p>
<h2 id="heading-what-are-mvps">What are MVPs?</h2>
<p>Dating back not too long ago - 2001 - the acronym has been coined, which stands for Minimum Viable Product. Before a product starts generating profit, its developers need to understand its market extremely well. They need to detect the most significant problems clients face and solve them. Determining what makes the problem significant is also what defines the product.</p>
<p>By using an MVP, developers can concentrate directly on the said problem, without pouring too many resources into a more advanced form of the product. It is more important to see if the product solves the customer's problem first. Then comes the consolidation.</p>
<p>For a business, efficiency is key. It is much more efficient for product development to take its course in tandem with customer research. This way, both issues, and solutions can be handled in real-time.</p>
<p>More precisely, an MVP is the skeleton of a human body, the outline of an essay, and the stage setup of a concert. It is the bare frame that bears the least number of features, focusing on only solving the most important one it was designed to solve. Since solving that issue is the focal point of an MVP, it needs to function perfectly in order to not create additional problems along the way while the infrastructure is still in its fetal stage.</p>
<p>Eric Ries - author of the book "<a target="_blank" href="http://theleanstartup.com/">The Lean Startup</a>" - defines an MVP as the stage of a product in which as much client data collection is permitted, by undergoing the least amount of effort. It is the stage that helps a team understand how their product can start making money from that point on.
Some common MVP practices
To thoroughly understand what minimum and viable means when it comes to a product, it is helpful to look at some common practices that led MVPs to become successful. Six such practices come to mind:</p>
<ul>
<li>Landing page</li>
<li>Media (video or animation)</li>
<li>Email</li>
<li>Piecemeal</li>
<li>Illusion</li>
<li>Concierge</li>
</ul>
<p>Any product, regardless of its level of functionality, requires a brief description of what it does. Ideally, this information should fit on a <strong>landing page</strong>. Its main focus is to shine some visibility on the product. A customer's curiosity brings value to the product, which is what a founder should be initially seeking and feeding off of, to know where to go next. In this case, value is measured by emotional responses, meaning customers found some solace, thus making the problem more easily identifiable.</p>
<p>People have different learning methods. They are stimulated either visually, sonically, or creatively. If reading about a product still does not help them make the connections they need to understand a product, a <strong>video</strong> or an <strong>animation</strong> would be more useful. Brief as it might be, the essence of a product's function can be extracted and transformed - or edited - in moving images. After the emotional responses have been triggered, slap a call to action at the end of the video, and boom - you got yourself what is known as an opportunity in the corporate world.</p>
<p>It may seem old-fashioned but <strong>email campaigns</strong> are still effective. Granted, you need to build an initial contact list, but it only takes sending one email to test the waters and analyze the recipients' responses.
It would be nice to have some sort of demo version for everything we buy but are initially unsure of. Like testing a melon at a market, or taking a new car for a ride from a dealership lot. In terms of using this piecemeal approach for an MVP, a founder can extract what they believe to be the most important and useful features of a product that still make it viable on its own, limited as it is.</p>
<p>With a little pizzazz to collect user responses and create intent to buy, the development team doesn't have to go out of their way to make a functioning product that seems as easy to use as a demo version, but is really all there is to get the job done. In the beginning, this method requires a more "hand-made" tactic before the team can fully automate its functionality. Just to get the pulse and explore the potential buying power. Just until it gets too difficult to operate "manually".</p>
<p>If you have an e-commerce platform on your hands, the <strong>illusion</strong> (sometimes called <strong>Wizard of Oz</strong>) approach is ideal. While your company does not physically carry the products on the page, customers still need to be drawn to purchase them from vendors. Your platform is the one that draws them in, and that ultimately generates traffic to your page.</p>
<p>Your illusion game needs to be top notch…meaning you have to make the customers' buying experience one that they cannot find anywhere else. This can only be achieved by trial and error, constantly changing the way the platform looks and taking notes on when there's an interest growth spike.</p>
<p>Similar to the piecemeal approach, the <strong>concierge</strong> approach relies on manually operating a process before turning the operation into a product. In this case, manual operation refers to personal interaction with customers. Building trust the old fashioned way! After customers develop "feelings" for the way your company treated them, they will most likely stay on board after you automate the services as well.</p>
<h2 id="heading-how-can-startups-benefit-from-mvps">How Can Startups Benefit from MVPs?</h2>
<p>Does a customer really need your product? An MVP can provide the best answer.</p>
<p>There is no need to waste resources, effort, and budget before finding the answer out. A low-code version of the product's main functionality is all the customer needs to decide if they need it, and for you to decide whether you found your niche. This version can actually demonstrate your product's ability to the customer which generates the most important criteria for a business owner: <strong>validation</strong>.</p>
<p>The customer will explore the product thoroughly in order to test its validity. Although an MVP is a very basic version of the final result, it needs to work in all of the <strong>iterations</strong> that the customer is able to explore. This puts more pressure on the development team, but will take an insurmountable weight off their shoulders in the long run.</p>
<p><strong>Customer feedback</strong> is crucial but not immeasurably important. Development team and management should not cling on to every single critique or feedback, but instead draw a conclusion in regards to what direction to take. After all, the big aim is to head towards product-market fit.</p>
<p>If your product is so innovative that it is unprecedented on the market, you may have struck gold! But as any pirate or miner will tell you, gold must be kept well-protected. Having first entry to market, your product may be so revolutionary that the market is not yet educated or prepared for the benefits it can generate. By using an MVP you can also gradually infiltrate the concept on the market before competitors find a better way to display the value of the product to potential customers.</p>
<p>An MVP allows a startup to reduce the risk of failure by spending less resources such as time and money. After all, this is the very definition of <strong>effective investment management</strong>. A smaller budget helps a team to focus on where the money is necessary and where it actually ends up helping. This implies simplifying demands, cutting out unnecessary tasks and expenses, and most importantly, being vigilant in getting an accurate pulse of the market.</p>
<p>As difficult as it may be to fathom, there are solutions on the market that tick all the boxes above. Languages and frameworks that support an MVP for as long as needed before the application takes off. One such useful programming language is Ruby on Rails.</p>
<h2 id="heading-ruby-on-rails-doing-the-heavy-lifting-for-you">Ruby on Rails: Doing the Heavy-Lifting For You</h2>
<p>Two words that should titillate your interest: programmer productivity.</p>
<p>When it comes to syntax, language, and afferent suite of tools, programmers sigh with relief knowing that they can build faster and worry less about basic code and database structures. Numerous Silicon Valley startups such as Airbnb, Shopify, Github, Twitter, Hulu, Dribble, Kickstarter, and even Tesla have used RoR to expand within the market.</p>
<p>Instead of wasting your budget and your programming team's time for basic - but necessary - coding, by using Ruby on Rails they can get right to building the essence of your product, while you and your clients can observe the results much quicker and solve any issues on the fly.</p>
<p>Similar to frameworks like Java, Python, and PHP, RoR uses a model-view-controller (<strong>MVC</strong>) architectural pattern. The model refers to the logic of the application, the view represents the template files that result in the data's visual representation, and the controller is the connecting piece between the latter two. With the help of an MVC arch, the application logic is kept clean and applications become flexible.</p>
<p>Aside from MVC, RoR also relies on convention-over-configuration (<strong>CoC</strong>) and the Don't Repeat Yourself (<strong>DRY</strong>) principle.</p>
<p>CoC refers to frameworks setting "sensible defaults" so that programmers don't have to make every little decision, instead they get to focus more on building the actual application.</p>
<p>DRY prevents programmers from using repetition in their codebase, which makes files and functions easier to maintain, debug, and most important of all…understand.</p>
<h2 id="heading-pros">Pros</h2>
<p>It is important to note that an MVP is not a Beta version of a product. While Beta versions aid in finding bugs, user experience, stability, and reliability issues, they are meant for a group of tech savvy people known as Beta testers.</p>
<p>An MVP relies on the viable aspect by being able to function well for normal customers. The aim is for the customers to appreciate the value and understand how the product can solve their problems. It is necessary for the product to work well and impress potential customers by solving their outstanding problem.</p>
<p>So let's go over the pros of using Ruby on Rails one more time:</p>
<ul>
<li>Takes little time to develop</li>
<li>Easy to read and understand</li>
<li>Free to use</li>
<li>Highly scalable</li>
<li>Secure framework</li>
<li>Helpful community</li>
</ul>
<p>Sounds perfect, but there has to be a dealbreaker, right?</p>
<h2 id="heading-cons">Cons</h2>
<p>For startup CEOs, the <strong>cost</strong> might be the main con. While RoR is free to use, the few programmers who can develop a solid base will charge 100K + per year.</p>
<p>Even if you dispose of that kind of money, it is <strong>difficult to find</strong> RoR programmers on every corner. Since it is not the most commonly used language and framework, there is quite a niche of programmers that can even take on RoR-based projects.</p>
<p>Since these two aspects might be discouraging enough for a startup team to go through with using RoR, they may eventually <strong>slow down progress</strong>. Paying copious amounts of money and wasting precious time on fixing bugs and not understanding the needs of the market entirely are not efficient uses of resources. During this time the competition might prosper, rendering your product inferior or even outdated by the time it is finished.</p>
<h2 id="heading-solution">Solution</h2>
<p>Overseeing and successfully managing all the activities a startup implies is harrowing enough. And although they are paid for their efforts, even programmers would much rather concentrate on programming the main function of a product, rather than waste time in the "pre-production" phase.</p>
<p>Ideally, there should be a platform that is as easy to use as Wordpress or Wix. A platform that makes the process easy to understand and use for anyone. A platform from which you can choose RoR templates, features, resources, common actions (such as deleting a page or duplicating a page), an area where you can edit results, all the while the activity is transparent, easy to access for programmers, and works quickly and efficiently.</p>
<p>Such a platform is <a target="_blank" href="https://avohq.io">Avo</a>.</p>
<p>Avo essentially takes care of building everything else that is not the absolute core functionality of the product. By using Avo, you don't have to allocate big budgets to developers to build the boilerplate.</p>
<p>You are better off using the fortune you save on basic infrastructure developing on other marketing practices to get your product in the hands of those that actually need it.</p>
<p>While your programming team concentrates on the core functionality, here are the ways you will be ahead of schedule on:</p>
<ul>
<li>scouting the market</li>
<li>generating demand</li>
<li>creating supply</li>
<li>securing your place on the market (even making it indispensable)</li>
</ul>
<p>All the while your competitors will barely be at step one.</p>
<p>In comparing the subscription-based Avo to a platform like Wordpress but for Ruby on Rails, it is also implied that it makes your production time at least 10 times more efficient.</p>
<p>No additional costs, no scouting for the ideal RoR programmer, just an app developed by programmers who have faced the same problems and developed a solution. A solution that will save you money, time, stress, and a lot of extra hassle to just turn your product into reality as quickly and effortlessly as possible.</p>
<hr />
<h2 id="heading-requirements-for-implementing-an-mvp">Requirements for implementing an MVP</h2>
<p>While some products are less likely to have an obvious and compact explanation for their value and functionality, others can be summed up in a basic elevator pitch. Regardless, there are some factors to take into consideration before deciding on implementing an MVP approach.</p>
<h3 id="heading-aligned-ideology-within-the-team">Aligned Ideology Within the Team</h3>
<p>A team's first real test is coming up with the Proof of Concept (PoC). This usually resembles the final product, except it is just an early model. This is where hypotheses and outcomes are discussed and explored. Demonstrating the functionality of the product will ascertain the theory that lies behind it.</p>
<p>This means the team has to be on the same wavelength. It should be strong enough to not crumble during the brainstorming, documentation, and <a target="_blank" href="https://leanstack.com/lean-canvas">Lean Canvas</a> phases. After weak assumptions are expelled and timing and presentation types are decided upon, the team will already have gone through enough consolidation phases to have a clearer purpose and work ethic.</p>
<p>After all, a healthy and unified team is the strongest type, as the results always show. An MVP is guaranteed to benefit from this type of collective attitude.</p>
<h3 id="heading-additional-staffing">Additional Staffing</h3>
<p>After the PoC phase, the team needs to start taking each following step of the product very seriously in terms of execution. A strong and effective MVP requires sophistication.</p>
<p>A team should look into adding to their staff as a necessary investment to their operation. Specifically, developers with knowledge of back-end technology, as well as front-end technologies.</p>
<h3 id="heading-prototype-evolution">Prototype Evolution</h3>
<p>If a product works, it needs to be scaled up to satisfy mass demand. This means the architecture of information is crucial in setting the product's stability and scalability. The natural progression of a product should be:</p>
<ol>
<li>Proof of Concept</li>
<li>Prototype</li>
<li>MVP</li>
</ol>
<p>Without having to give up on quality, scalability should be kept in mind with each step forward. Every factor that plays a positive role in reliability should be kept from one stage to another, and improved upon.</p>
<h3 id="heading-mvp-construction">MVP Construction</h3>
<p>Finally, the actual building of the MVP. Based on initial interest and first experiences reported by users, the experimentation stage should be very advanced by now and the business model is on the verge of confirming or infirming initial theories. Namely, as a startup owner, you should have by now been able to tick the following boxes:</p>
<ul>
<li>Market and customer segment targeting</li>
<li>Finding problems within customer segments and trying to find viable solutions</li>
<li>Offering your solution as having unique value on the market</li>
<li>Setting up communication and distribution channels</li>
<li>Setting up revenue streams and possible future collaborations</li>
<li>Assessing the costs - how much goes in and out to sustain the operation until it takes off</li>
</ul>
<p>If your experimentation stage has undergone all of these (and afferent) bullet points, the team's path should be clear and ready to start integrating the MVP process.</p>
<h3 id="heading-is-an-mvp-a-viable-solution-for-your-startup">Is an MVP a viable solution for your startup?</h3>
<p>Since knowledge is the driving force behind the startup, it is also its kerosene until it takes off. An MVP is a gap. It helps a company turn knowledge into business.</p>
<p>By collecting customer data, a Minimum Viable Product aims to validate initial assumptions and hypotheses a team has when embarking on this startup trip, and turn them into a viable business model.</p>
<p>Before looking for external funding, startup companies have to be unified in the faith they have in their product. This can only happen by receiving customer validation: if one customer finds value in the product, they won't be alone. Thus the value will increase, and the faith will drive the team to gradually go "all in". A functioning product built with a minimum budget is exactly what fills that gap and what fuels the next exciting stages.</p>
<p>As a bonus - which can turn out to work in their favor - a team can also explore if there is any competition for what their product has to offer, and take notes on why customers are looking elsewhere after not being satisfied with those solutions. You could even be the first that presents this solution!</p>
<p>But in order not to jump ahead too much or even pose a threat to the existing market, an MVP also helps in maintaining balance and somewhat of a low-profile in its initial stages. Does your product relate to the potential an MVP serves? It depends on how far you are willing to take it, how quickly, and how much you believe in its success. The ball is in your court now.</p>
]]></content:encoded></item><item><title><![CDATA[Front page of Hacker News, 2nd product of the day on Product Hunt and featured in one of the biggest Ruby newsletters]]></title><description><![CDATA[Article originally posted on our blog.
We've had a crazy marketing week 🎉 The biggest public launches yet.
A week before, I planned a Product Hunt but didn't launch it because… I was lazy.

    


On Tuesday, I finished the work on the Product Hunt ...]]></description><link>https://blog.adrianthedev.com/front-page-of-hacker-news-2nd-product-of-the-day-on-product-hunt-and-featured-in-one-of-the-biggest-ruby-newsletters</link><guid isPermaLink="true">https://blog.adrianthedev.com/front-page-of-hacker-news-2nd-product-of-the-day-on-product-hunt-and-featured-in-one-of-the-biggest-ruby-newsletters</guid><category><![CDATA[product hunt]]></category><category><![CDATA[launch]]></category><category><![CDATA[ProductHunt]]></category><category><![CDATA[hackernews]]></category><category><![CDATA[ruby weekly]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Fri, 24 Jun 2022 21:08:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1656106255908/zdS7tbiZ2.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Article originally posted on <a target="_blank" href="https://avohq.io/blog/launch-on-hacker-news-product-hunt-and-newsletter-ruby-weekly">our blog</a>.</p>
<p>We've had a crazy marketing week 🎉 The biggest public launches yet.</p>
<p>A week before, I planned a Product Hunt but didn't launch it because… I was lazy.</p>
<div class="flex justify-center">
    <img src="https://avohq.io/img/blog/product-launches/lazy.gif" alt="Adrian being lazy" />
</div>

<p>On Tuesday, I finished the work on the Product Hunt campaign and set it to launch on Thursday. I prepped a discount code, told my friends and the community I would launch the campaign, and left it there.</p>
<h1 id="heading-hacker-news">Hacker News</h1>
<p>At about 5:00 PM, I started fiddling with Hacker News. I opened the new section and wrote <code>Show HN: Build Ruby on Rails apps 10x faster – Avo</code> in the title and added a link to the homepage. I posted on HN before about Avo, but I think the messaging was wrong. The product wasn't mature enough, and I didn't communicate well about it.</p>
<p>But I said, f*ck it! Let's submit this! I wrote the first comment addressing many of the issues and questions users brought up in the past. I watched the post a bit and got 5-7 votes. I had a call and went into a meeting. I started getting newsletter subscription notifications and a few trials during the meeting. That was weird. When I came out of the meeting, we were on the front page 🎉.</p>
<div class="flex justify-center">
    <img src="https://avohq.io/img/blog/product-launches/champagne.gif" alt="On the front page of Hacker News" />
</div>

<p>People started commenting; the points began growing.</p>
<p>A good part of the comments from HN were very pertinent questions about how "does it integrate with current apps?", "is it easy to get started?", "will it work in a large app?", and so on. Some weren't. The main ideas were:</p>
<ul>
<li>"how to get started"</li>
<li>"who is it suited for?"</li>
<li>"can it be used in a medium-sized/large app?"</li>
<li>"how does it support this/that package?"</li>
<li>"how does it compare with the (wrong or right) alternatives?", "Make a comparison."</li>
<li>"does it do this or that?"</li>
<li>"Rails is dead"</li>
<li>"Rails is alive"</li>
<li>"I'm sorry I don't work with Rails with such a wonderful ecosystem"</li>
<li>"I'm excited for these kinds of tools popping up"</li>
<li>"this is a paid product 😠 (mad face)" (although I mentioned that before)</li>
<li>"why is it so expensive? why is it a subscription? can I have it for free? pricing is misleading/unclear."</li>
<li>"do people make money with these kinds of projects?"</li>
<li>"why is it called that?"</li>
<li>"you lie! you can't build something that fast?" (yes you can 😎)</li>
<li>"the demo site is slow" (my bad there. it's hosted on heroku hobby plan)</li>
<li>"Adrian provides the best support. Adrian releases every week. Adrian is awesome 😎!" (I may have distorted that a bit)</li>
<li>"looks amazing. what a breath of fresh air"</li>
<li>"why won't you build this for JS/python?"</li>
<li>"this delivers value!"</li>
<li>"this is useless. I can build it myself"</li>
</ul>
<p>I loved every comment. Good and bad! This shouldn't come as a surprise to you, but you should want to hear the bad feedback about your product. If someone says only good things, there might be a problem there. Ask them follow-up questions about the things you know are missing. They will start telling you that "oh yes. that is missing from your product too. I had a hard time without it". But that's a post for another time.</p>
<p>One not-so-good thing that happened was that the Product Hunt campaign that was set to go public on Thursday, was triggered by mistake (still not sure how) during the HN launch. So more than half a day of campaigning seemed wasted.</p>
<p>I had a link on the homepage previewing the Product Hunt launch. I spoke with PH support, and they reset it for Thursday. Crysis averted 😮‍💨</p>
<p>The stats for the HN launch look like this:</p>
<ul>
<li>8K site visitors and 24K pageviews 🚀</li>
<li>about 100-120 users at a time on the site. the VPS with dokku (fantastic tool!) held on very nicely. I even made a few deploys during the peak hours.</li>
<li>~300 points. ~160 comments (almost half were mine responding)</li>
<li>2-3K youtube views (I have a walkthrough video on the homepage)</li>
<li>8 newsletter subscriptions</li>
<li>maybe 10 new Twitter followers</li>
<li>3-4 new Discord users</li>
<li>5 trials started</li>
<li>Usage increased by 20% (people trying it out)</li>
</ul>
<p>You can find the post <a href="https://news.ycombinator.com/item?id=31824877" target="_blank">here</a>.</p>
<p>I must say I loved every moment of being on the front page. It was a milestone for the indie hacker geek inside of me.</p>
<div class="flex justify-center">
    <img src="https://avohq.io/img/blog/product-launches/nerd.gif" alt="Adrian being a nerd" />
</div>


<h1 id="heading-product-hunt">Product Hunt</h1>
<p>Let me set the stage for <strong>how Product Hunt works</strong>. Every day there's a 24-hour window when people launch products. It starts at 00:01 AM PDT and should end in 24 hours. Products get upvoted and at the end of the day you get a badge (1st, 2nd, 3rd product of the day) or if you got featured (top 8-12 products). The unfeatured ones fall somewhere below a "more" button on the homepage (instant death on PH). You also get comments on the product. There are a few more things involved (weekly rank, yearly golden kitty award, reviews, etc), but that's the gist. You'd like to rank as high as possible. The ranking is a secret algorithm that considers votes, comments, how people end up on PH, what they do before voting, and more.</p>
<p>Back to our launch. I live in Romania (EEST time), so the launch starts at 10:00 AM. Perfect to start campaigning. When I say campaigning, I mean going on groups of like-minded people and posting about the product and the launch. For us, those people were, or had these interests:</p>
<ul>
<li>indie developers</li>
<li>founders</li>
<li>growth hacking</li>
<li>low-code/no-code</li>
<li>start-ups</li>
<li>marketing</li>
<li>tech leads</li>
<li>agencies</li>
</ul>
<p>These people gave us the most encouragement and feedback about the product.</p>
<p>They were the <em>new people</em> that gave their support. The established ones were Avo users and customers.</p>
<p>I believe they made <strong>the difference</strong> with their comments. You can always spot the actual customer of the product in the comments. You'll see people go out of their way to let the world know their opinion on it: </p>
<ul>
<li><em>Avo is legit!</em></li>
<li><em>Avo is the first well documented admin gem</em></li>
<li><em>Thank you for this wonderful product</em></li>
<li><em>Avo has been a game changer for our team</em></li>
<li><em>Avo is hands-down the best solution we've found</em></li>
<li><em>Avo inspires me to quickly try new ideas</em></li>
<li><em>This is a must-use by engineering teams worldwide</em></li>
<li><em>I've built this in-house and watched it decay and become useless so many times</em></li>
<li><em>That's what Avo is to me! It's Rails on Rails!</em></li>
<li><em>It saved us hundreds of hours of development work and we could focus on our main business</em></li>
</ul>
<p>I'd add all the reviews, but I'm going to stop there 😎</p>
<p>The third and equally important category was the Rails community. I posted from my and Avo's Twitter account about our launch. There is a wonderful Twitter community called <strong>Ruby on Rails</strong> where I never post about Avo. People tend to get a bit "aggressive" toward paid products. Although Avo has quite a robust free option, everyone focuses on the fact that it's PrOMoTiOn. Plenty of paid products are advertised in communities (not only that community), but somehow, people pick on mine. Or at least that's my impression, but that's a rant for another day.</p>
<p>Back to posting on the Ruby on Rails Twitter community; I made the post as honest as possible. "There's a Ruby on Rails package #2 on Product Hunt. Let's show our support." And the folks there were very cool about it (there's another "closed circle" community where the meanness and spiteness are through the roof, IMHO). I didn't hear any mean comments, and some liked the post.</p>
<div class="flex justify-center">
    <img src="https://avohq.io/img/blog/product-launches/time.gif" alt="Adrian passing the time" />
</div>

<p>The PH day went by. Somewhere in the first 4-5 hours, we reached the top three and second place quite quickly afterward. We were behind the #1 by about 10-30 votes during the day. The number one product was "A Chrome extension for beautiful screenshots". So it's more of a consumer-facing product than ours. I suspect they had to do a little less work to campaign 🤔. I still think we were lucky that a big company like Stripe, Shopify, Apple, or another big start-up didn't announce a significant product. Thursday is considered a high-traffic day on PH (Tuesday and Wednesday are the other two).</p>
<div class="flex justify-center">
    <img src="https://avohq.io/img/blog/product-launches/broken.gif" alt="PH being broken" />
</div>

<p>Sometime after 16 hours of the PH day, something happened on PH; I suspect a bug. We had more votes and kind of the same number of comments as the #1 and we were still #2. We also started to see "2nd product of the day" badge on our page (and "1st product" for #1). That threw us off a bit. Even the private launch dashboard did not show the countdown anymore. We thought "the fight was over". It was 3 AM on our end, and we were beat. It's quite draining psychologically to "hunt" for that feedback, grow on the podium, be so close to the top and not get there. So I spoke with David, my brother, and went to sleep. It was still a good result and a good launch.</p>
<p>During the night, David sent me a message that we dropped on to 3rd, then again on 2nd. PH definitely does some cleanup with the votes. We lost about 20-30 votes after the 24h window closed. Some products lost 100 votes. Not sure what happened there, but we're still happy we haven't lost our position.</p>
<div class="flex justify-center">
    <img src="https://avohq.io/img/blog/product-launches/second-place.gif" alt="Second place" />
</div>

<p>You'll find Avo's PH launch <a href="https://www.producthunt.com/posts/avo-for-rails" target="_blank">here</a>.</p>
<h1 id="heading-ruby-weekly">Ruby Weekly</h1>
<p>One of the biggest newsletters in the Ruby community is Ruby Weekly, and it comes out on a Thursday. I knew that. I could have anticipated they would pick up on the Hacker News article, feature us, and hold off the Product Hunt, but I didn't.</p>
<p>So we got featured on Ruby Weekly. That's usually a good thing (this time too 🙏), but I wanted to measure each campaign's results, not all together. I'm grateful for the featuring (please don't stop doing that 😊), and we got some traffic from there too. I guess it helped in a way because it drove traffic to our website, where we had the Product Hunt badge visible.</p>
<p>The stats for Thursday look like so:</p>
<ul>
<li>1.6K site visitors and 7K pageviews</li>
<li>one newsletter subscriber</li>
<li>one trial</li>
<li>2nd Product of the Day badge on our homepage 😎</li>
</ul>
<h1 id="heading-conclusions">Conclusions</h1>
<p>For such a niche and technical product like Avo, I'd say we got much more ROI for the HN post than for PH. We worked our asses off to bring in traffic, and there were just a few conversions. There might be wins in the long run from SEO and the 2nd product of the day PH badge. For HN, we did considerably less. Primarily respond to questions.</p>
<h1 id="heading-what-next">What next?</h1>
<p>David and I are excited about things to come. The community definitely noticed Avo and is curious about it. We have to work more on how we communicate about the product.</p>
<p>There is a ton of work we still have to do on the development side to make this the dream platform we'd like it to become.</p>
<h1 id="heading-keep-up-with-the-updates">Keep up with the updates</h1>
<p>You can keep up with updates by <a href="https://avohq.io/#subscribe" target="_blank">subscribing to our newsletter</a>, <a href="https://twitter.com/avo_hq" target="_blank">following us on Twitter</a>, <a href="https://avohq.io/chat" target="_blank">joining our Discord server</a>, and by <a href="https://avohq.io/repo" target="_blank">starring the GitHub repo ⭐️</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Auto re-load Rails initializers (and other files) in development]]></title><description><![CDATA[This article was originally published on avo.cool
I fixed a shitty situation I created for myself two years back a few days back. What a fantastic feeling that was. I'm still in awe when everything just works.
When I first started to work on Avo, I d...]]></description><link>https://blog.adrianthedev.com/auto-re-load-rails-initializers-and-other-files-in-development</link><guid isPermaLink="true">https://blog.adrianthedev.com/auto-re-load-rails-initializers-and-other-files-in-development</guid><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[Developer Tools]]></category><category><![CDATA[Developer]]></category><category><![CDATA[admin]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Mon, 11 Apr 2022 08:05:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1649664250752/53STlS2jc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This article was originally published on <a target="_blank" href="https://avo.cool/blog/auto-reload-rails-initializers-and-other-files-in-development">avo.cool</a></em></p>
<p>I fixed a shitty situation I created for myself two years back a few days back. What a fantastic feeling that was. I'm still in awe when everything just works.</p>
<p>When I first started to work on Avo, I didn't know much about Rails' inner workings and file-reloading. So as some might not know, Avo helps developers ship apps quickly. Using a few declarative configuration files that the developer is generating in their own app, it does that. Those files are inherited from a few base files <code>UserResource</code> from <code>BaseResource</code>, <code>ToggleAdminAction</code> from <code>BaseAction</code>, <code>TextField</code> from <code>BaseField</code>, and so on.</p>
<p>The issue arose in Avo's development process. When you were making an update to the <code>BaseResource</code>, the changes were not showing up in the <code>Dummy</code> app. The server was not picking them up and wasn't reloading those inherited classes. You had to restart the server for those changes to come into effect.</p>
<p>Over the years, I got pretty clever on how to work around this because there are more pressing issues that I can fix with my time. But I was still thinking about it and coming back to it to try to fix it from time to time.</p>
<h2 id="heading-how-did-others-fix-it">How did others fix it?</h2>
<p>I checked all the <a target="_blank" href="https://guides.rubyonrails.org/autoloading_and_reloading_constants.html">guides</a> on autoreloading, literally read the whole docs page and some of the source code of <a target="_blank" href="https://github.com/fxn/zeitwerk">zeitwerk</a>, checked out a lot of <a target="_blank" href="https://rmosolgo.github.io/ruby/rails/2017/04/12/watching-files-during-rails-development.html">purpose made</a> <a target="_blank" href="https://blog.arkency.com/2014/11/dont-forget-about-eager-load-when-extending-autoload/">tutorials</a> about code reloading in development and nothing really worked as advertised. I couldn't wrap my head around why it was not working.</p>
<p>Until Friday; I asked myself, "what have others done to fix this?". Then, I remembered that <a target="_blank" href="https://twitter.com/dhh">DHH</a> posted an early demo video of importmaps where he stated something along the lines of "we need to restart the server for the importmaps file to register changes. This is something that we'll fix before release...". So, it's released now, so they've fixed it; time to see what they did.</p>
<p>They built this <code>Reloader</code> class that holds all the configuration and the <code>reload!</code> method.</p>
<pre><code class="lang-ruby"><span class="hljs-comment"># lib/importmap/reloader.rb</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Importmap::Reloader</span></span>
  delegate <span class="hljs-symbol">:execute_if_updated</span>, <span class="hljs-symbol">:execute</span>, <span class="hljs-symbol">:updated?</span>, <span class="hljs-symbol">to:</span> <span class="hljs-symbol">:updater</span>

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">reload!</span></span>
    import_map_paths.each { <span class="hljs-params">|path|</span> Rails.application.importmap.draw(path) }
  <span class="hljs-keyword">end</span>

  private
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">updater</span></span>
      @updater <span class="hljs-params">||</span>= config.file_watcher.new(import_map_paths) { reload! }
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">import_map_paths</span></span>
      config.importmap.paths
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">config</span></span>
      Rails.application.config
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>

<span class="hljs-comment"># engine</span>
initializer <span class="hljs-string">"importmap.reloader"</span> <span class="hljs-keyword">do</span> <span class="hljs-params">|app|</span>
  Importmap::Reloader.new.tap <span class="hljs-keyword">do</span> <span class="hljs-params">|reloader|</span>
    reloader.execute
    app.reloaders &lt;&lt; reloader
    app.reloader.to_run { reloader.execute }
  <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>So what are they doing here? First, the <code>reload!</code> method tells Rails what to do when it needs to run. In their case, it takes the importmap files <code>config.importmap.paths</code> and runs <code>Rails.application.importmap.draw</code> for each one. So basically, re-registering the importmaps. Next, they create a file watcher that watches over the files they need.</p>
<p>In the initializer, they add the <code>reloader</code> to the app's <code>reloaders</code> and instruct the app what to do when changes have been detected.</p>
<h2 id="heading-translate-that-to-watching-and-reloading-the-initializer">Translate that to watching and reloading the initializer</h2>
<p>How does that translate to watching and reloading the initializer and our base classes? We'll tweak a few methods in the reloader.</p>
<p>First, define the paths that we want to watch. For example, we'd like to watch for changes in the initializer (a file) and the whole <code>lib</code> directory. So we're going to remove <code>paths</code> and add two methods, <code>files</code> and <code>directories</code>.</p>
<pre><code class="lang-ruby"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">files</span></span>
  <span class="hljs-comment"># we want to watch some files no matter what</span>
  paths = [
    Rails.root.join(<span class="hljs-string">"config"</span>, <span class="hljs-string">"initializers"</span>, <span class="hljs-string">"avo.rb"</span>),
  ]

  paths
<span class="hljs-keyword">end</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">directories</span></span>
  dirs = {}

  <span class="hljs-comment"># watch the lib directory in Avo development</span>
  <span class="hljs-keyword">if</span> reload_lib?
    dirs[Avo::Engine.root.join(<span class="hljs-string">"lib"</span>, <span class="hljs-string">"avo"</span>).to_s] = [<span class="hljs-string">"rb"</span>]
  <span class="hljs-keyword">end</span>

  dirs
<span class="hljs-keyword">end</span>
</code></pre>
<p>You might have noticed the <code>reload_lib?</code> method. That's there to instruct Rails to reload the <code>lib</code> directory only when we tell it to or doing development on Avo, not the parent app.</p>
<pre><code class="lang-ruby"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">reload_lib?</span></span>
  Avo::IN_DEVELOPMENT <span class="hljs-params">||</span> ENV[<span class="hljs-string">'AVO_RELOAD_LIB_DIR'</span>]
<span class="hljs-keyword">end</span>
</code></pre>
<p>Next, we will change what the <code>reload!</code> method does. We're going to reload all the files in <code>files</code> and all the files in the directories we specified.</p>
<pre><code class="lang-ruby"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">reload!</span></span>
  <span class="hljs-comment"># reload all files declared in paths</span>
  files.each { <span class="hljs-params">|file|</span> load file }

  <span class="hljs-comment"># reload all files declared in each directory</span>
  directories.keys.each <span class="hljs-keyword">do</span> <span class="hljs-params">|dir|</span>
    Dir.glob(<span class="hljs-string">"<span class="hljs-subst">#{dir}</span>/**/*.rb"</span>.to_s).each { <span class="hljs-params">|file|</span> load file }
  <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<h2 id="heading-put-it-all-together">Put it all together</h2>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Avo::Reloader</span></span>
  delegate <span class="hljs-symbol">:execute_if_updated</span>, <span class="hljs-symbol">:execute</span>, <span class="hljs-symbol">:updated?</span>, <span class="hljs-symbol">to:</span> <span class="hljs-symbol">:updater</span>

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">reload!</span></span>
    <span class="hljs-comment"># reload all files declared in paths</span>
    files.each { <span class="hljs-params">|file|</span> load file }

    <span class="hljs-comment"># reload all files declared in each directory</span>
    directories.keys.each <span class="hljs-keyword">do</span> <span class="hljs-params">|dir|</span>
      Dir.glob(<span class="hljs-string">"<span class="hljs-subst">#{dir}</span>/**/*.rb"</span>.to_s).each { <span class="hljs-params">|file|</span> load file }
    <span class="hljs-keyword">end</span>
  <span class="hljs-keyword">end</span>

  private
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">updater</span></span>
      @updater <span class="hljs-params">||</span>= config.file_watcher.new(files, directories) { reload! }
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">files</span></span>
      <span class="hljs-comment"># we want to watch some files no matter what</span>
      paths = [
        Rails.root.join(<span class="hljs-string">"config"</span>, <span class="hljs-string">"initializers"</span>, <span class="hljs-string">"avo.rb"</span>),
      ]

      <span class="hljs-comment"># we want to watch some files only in Avo development</span>
      <span class="hljs-keyword">if</span> reload_lib?
        paths += []
      <span class="hljs-keyword">end</span>

      paths
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">directories</span></span>
      dirs = {}

      <span class="hljs-comment"># watch the lib directory in Avo development</span>
      <span class="hljs-keyword">if</span> reload_lib?
        dirs[Avo::Engine.root.join(<span class="hljs-string">"lib"</span>, <span class="hljs-string">"avo"</span>).to_s] = [<span class="hljs-string">"rb"</span>]
      <span class="hljs-keyword">end</span>

      dirs
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">config</span></span>
      Rails.application.config
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">reload_lib?</span></span>
      Avo::IN_DEVELOPMENT <span class="hljs-params">||</span> ENV[<span class="hljs-string">'AVO_RELOAD_LIB_DIR'</span>]
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>The Rails app now knows what to do when something has changed in the parent app. It also knows to watch over the paths that we specified. So now, when you make a change in the initializer or any file in the <code>lib</code> directory, Rails will pick up those changes without you needing to reload the whole server.</p>
<p>I hope this helps you create better apps faster.</p>
<p>PS: If you want to create apps even faster, try out Avo. We sweat on the little details, so you don't have to.</p>
<p><a target="_blank" href="https://avo.cool">https://avo.cool</a></p>
]]></content:encoded></item><item><title><![CDATA[Dynamically re-use & lazy-load page using Hotwire]]></title><description><![CDATA[This article was originally published on avo.cool
Hotwire is a fantastic technology that helps you build dynamic websites without thinking about JavaScript.
When we re-wrote Avo from VueJS to Hotwire, when it first came out, we had to think about how...]]></description><link>https://blog.adrianthedev.com/dynamically-re-use-and-lazy-load-page-using-hotwire</link><guid isPermaLink="true">https://blog.adrianthedev.com/dynamically-re-use-and-lazy-load-page-using-hotwire</guid><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[admin]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[engineering]]></category><dc:creator><![CDATA[Adrian Marin]]></dc:creator><pubDate>Tue, 01 Mar 2022 15:39:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1646149027413/xUnOPmD7y.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This article was originally published on <a target="_blank" href="https://avohq.io/blog/dynamically-re-use-pages-with-hotwire">avo.cool</a></em></p>
<p>Hotwire is a fantastic technology that helps you build dynamic websites without thinking about JavaScript.</p>
<p>When we re-wrote Avo from VueJS to Hotwire, when it first came out, we had to think about how we could leverage it to our advantage. </p>
<p>One of the first things we did was to add dynamic turbo-frames around common pages.</p>
<p>For example, the <code>ResourceIndex</code> page is the page that usually displays the table with the requested resources (it shows the users on <code>/users</code>).
We knew that we could use that exact partial when we wanted to display the <code>has_many</code> association on the <code>ResourceShow</code> page but didn't know how at first. We could have extracted it to a partial and rendered it in the <code>ResourceShow</code> page underneath the record details, but the <code>ResourceShow</code> page would take a long time to load when you have many associations to one record.</p>
<p>We then came up with the idea to use a turbo-frame for that but still didn't want to use a partial.</p>
<p>Let's say we have <code>User</code> and <code>Team</code> models like so:</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Team</span> &lt; ApplicationRecord</span>
  has_many <span class="hljs-symbol">:users</span>
<span class="hljs-keyword">end</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> &lt; ApplicationRecord</span>
  belongs_to <span class="hljs-symbol">:team</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>The routes and controllers look like this:</p>
<pre><code class="lang-ruby">resources <span class="hljs-symbol">:posts</span>

get <span class="hljs-string">"/:resource_name/:id/:related_name/"</span>, <span class="hljs-symbol">to:</span> <span class="hljs-string">"associations#index"</span>
</code></pre>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BaseController</span> &lt; ApplicationController</span>
  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">index</span></span>
    <span class="hljs-comment"># if there's a query set up, use it, if not, set one up</span>
    <span class="hljs-keyword">unless</span> <span class="hljs-keyword">defined</span>? @query
      @query = @resource.<span class="hljs-keyword">class</span>.query_scope
    <span class="hljs-keyword">end</span>
  <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>

<span class="hljs-keyword">class</span> AssociationsController &lt; BaseController
  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">index</span></span>
    <span class="hljs-comment"># find the parent record and set the query</span>
    @query = @parent_model.public_send(params[<span class="hljs-symbol">:related_name</span>])
  <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>So what happens there? When a user goes to <code>/users</code>, they will see the list of users, and if they go to <code>/teams/TEAM_ID/users</code>, they should see the same list of users but scoped to the respective team.</p>
<p>In order to achieve this using <code>turbo-frame</code>s we'll add a lazy-loaded turbo frame on the <code>RecordShow</code> page with the <code>src</code> attribute set to the association path with the <code>?turbo_frame="has_many_users"</code> param added to the path <code>/teams/TEAM_ID/users?turbo_frame="has_many_users"</code> url.</p>
<pre><code class="lang-erb">&lt;!-- views/base/show.html.erb --&gt;

&lt;!-- record details here --&gt;

&lt;!-- association details below --&gt;
&lt;turbo-frame id="has_many_users" src="/teams/#{@team.id}/users?turbo_frame=has_many_users" target="_top"&gt;
  &lt;!-- Loading state --&gt;
&lt;/turbo-frame&gt;
</code></pre>
<p>Next, we should add a dynamic wrap around the <code>index.html.erb</code> partial like so.</p>
<pre><code class="lang-erb">&lt;!-- views/base/index.html.erb --&gt;

&lt;% if params[:turbo_frame].present? %&gt;
  &lt;turbo-frame id="&lt;%= params[:turbo_frame] %&gt;"&gt;
&lt;% end %&gt;

  &lt;!-- The list of records --&gt;

&lt;% if params[:turbo_frame].present? %&gt;
  &lt;/turbo-frame&gt;
&lt;% end %&gt;
</code></pre>
<p>What happens is that when the user loads a teams <code>Show</code> page <code>/teams/1</code>, that page will display with the lazy-loaded frame (so no impact on the performance of that page on load), which in turn, loads the association <code>Index</code> page with the <code>turbo_frame</code> param. That will add the <code>&lt;turbo-frame id="has_many_users"&gt;</code> tag around the template allowing Turbo to replace the content dynamically on the page.</p>
<p>We're re-using the actual <code>index.html.erb</code> template and the <code>BaseController#index</code> action.</p>
<p>Of course, this can be improved using some helpers and a partial.</p>
<pre><code class="lang-ruby"><span class="hljs-comment"># app/helpers/application_helper.rb</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">turbo_frame_wrap</span><span class="hljs-params">(name, &amp;block)</span></span>
  render <span class="hljs-symbol">layout:</span> <span class="hljs-string">"partials/turbo_frame_wrap"</span>, <span class="hljs-symbol">locals:</span> {<span class="hljs-symbol">name:</span> name} <span class="hljs-keyword">do</span>
    capture(&amp;block)
  <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<pre><code class="lang-erb">&lt;!-- app/views/partials/turbo_frame_wrap.html.erb --&gt;

&lt;% if name.present? %&gt;&lt;turbo-frame id="&lt;%= name %&gt;"&gt;&lt;% end %&gt;
  &lt;%= yield %&gt;
&lt;% if name.present? %&gt;&lt;/turbo-frame&gt;&lt;% end %&gt;
</code></pre>
<pre><code class="lang-erb">&lt;!-- views/base/show.html.erb --&gt;

&lt;!-- record details here --&gt;

&lt;!-- association details below --&gt;
&lt;turbo-frame id="&lt;%= turbo_frame %&gt;" src="&lt;%= frame_url %&gt;" target="_top"&gt;
  &lt;!-- Loading state --&gt;
&lt;/turbo-frame&gt;
</code></pre>
<pre><code class="lang-erb">&lt;!-- views/base/index.html.erb --&gt;

&lt;%= turbo_frame_wrap(params[:turbo_frame]) do %&gt;
  &lt;!-- The list of records --&gt;
&lt;% end %&gt;
</code></pre>
<p>You can do the same thing for <code>Show</code> pages too. We did with Avo.</p>
<p>You can find a more detailed example on Avo's GitHub repo.</p>
<ul>
<li><a target="_blank" href="https://github.com/avo-hq/avo/blob/main/app/views/avo/base/index.html.erb"><code>index.html.erb</code></a></li>
<li><a target="_blank" href="https://github.com/avo-hq/avo/blob/main/app/helpers/avo/application_helper.rb#L23"><code>turbo_frame_wrap</code></a></li>
<li><a target="_blank" href="https://github.com/avo-hq/avo/blob/main/app/components/avo/turbo_frame_wrapper_component.html.erb"><code>turbo_frame_wrapper_component.html.erb</code></a></li>
</ul>
<p>Stay cool and improve performance 💪</p>
<p><a target="_blank" href="https://avo.cool/">avo.cool/</a></p>
<p><a target="_blank" href="https://avo.cool/repo">avo.cool/repo</a></p>
<p><a target="_blank" href="https://avo.cool/feedback">avo.cool/feedback</a></p>
<p><a target="_blank" href="https://avo.cool/try">avo.cool/try</a></p>
]]></content:encoded></item></channel></rss>