RailsConf 2024

Riffing on Rails: sketch your way to better designed code

Riffing on Rails: sketch your way to better designed code

by Kasper Timm Hansen

Summary of 'Riffing on Rails: sketch your way to better designed code'

In this session presented at RailsConf 2024 by Kasper Timm Hansen, the focus is on improving code design through a technique known as 'riffing.' Riffing involves using a Ruby scratch file to explore ideas, define object names, responsibilities, and relationships, ultimately leading to better software design.

Key Points Discussed:

  • Introduction to Riffing: Riffing is described as a creative process that allows developers to sketch and iterate quickly without the constraints of traditional development methods. It offers the flexibility to explore different implementations and build shared understanding among team members.

  • The Need for Better Design Processes: Hansen emphasizes that creating perfect code instantaneously is unrealistic. Instead, he advocates for a process that permits exploration and fast iterations, critical to understanding project requirements and objectives.

  • Personal Experience with Riffing: Hansen shares his experiences from working on product teams where he often felt overwhelmed and anxious at the start of a new project. Through riffing, he found a way to alleviate these pressures and improve his design approach.

  • How to Riff: The method involves creating a single Ruby file focused on conventions and runnable code, which helps in understanding the problems better, while conventional processes like testing and migrations can be set aside temporarily.

  • Benefits of Riffing:

    • Lower startup costs and friction in development.
    • Encourages experimentation and exploration, leading to enhanced creativity and confidence in design.
    • Externalizes thoughts, reducing mental burdens and supporting better collaboration.
  • Live Demo Insights: Hansen conducted a live demonstration of riffing through a feature where users can favorite objects, illustrating how to start with basic controller logic and expand to user models without diving into complex associations prematurely.

  • Overcoming Challenges: Hansen acknowledges potential obstacles, such as the need for knowledge of APIs and feeling disoriented with a blank file. He emphasizes the importance of adhering to conventions and being open to exploration.

  • Collaboration and Teamwork: Riffing can improve collaboration and communication amongst team members, fostering an environment of creativity where everyone can engage in the design process together.

Conclusion:

Hansen concludes the session by inviting developers to adopt riffing in their workflows, especially during collaborative hack days. The takeaway is that riffing can serve as a valuable tool in a developer's toolkit to enhance coding practices and overcome the daunting aspects of software design.

00:00:10 Good afternoon, everyone. We're going to get started with our next session.
00:00:16 It is my honor to introduce Casper. Casper is an independent Rails consultant with a strong focus on clear naming and domain modeling.
00:00:27 He used to be on the Rails core team, where he reviewed and merged over 1,000 contributor pull requests. Casper is still involved in open source with his own gems that extend Rails further.
00:00:40 He has also contracted with Bullet Train, and he is happy to talk about that work as well. Casper is developing a new software development technique called riffing.
00:01:05 Okay, thank you. Welcome, everybody. I'm Casper, as the introduction said.
00:01:10 I used to be on the Rails core team, and we also developed features like the built-in test runner and Rails credentials forms. These days, I work as a consultant for various product teams and have also been an employee on multiple product teams.
00:01:40 Today, I'd like to talk about code design, which I define as figuring out the names, responsibilities, and relationships of objects within our systems. The focus is on how we can achieve better designs.
00:01:58 What I mean by that is we can't just create something instantly perfect. For me to achieve better design, I need a process that allows for exploration through fast iterations and a lot of practice with names, responsibilities, and relationships.
00:02:26 Part of what I want to emphasize is the need to play around with names, determine whether something should be an attribute, a full association, or a separate model, and so forth.
00:02:43 Let me share how this came about for me. While working on a product team, I often felt overwhelmed at the start of a new feature, unsure of how to begin or where to place the components.
00:03:05 Towards the end of the process, I often felt anxiety about whether I made the right choices or if I could have done better. This leaves us confused, wondering if we should have done things differently.
00:03:25 Eventually, I would arrive at a point where I just wanted to ship the project, which created defensiveness in code reviews - not ideal for either the reviewer or the reviewee.
00:03:47 My way out of that cycle was to open a blank Ruby file, sketch out my ideas, and I discovered that this method yielded much better results. Today, we will explore what riffing is, some of the benefits I've experienced, and some potential obstacles you might face if you decide to try it.
00:04:22 I will also attempt a live demo, which can be unpredictable, but I aim to show what it feels like.
00:04:37 First of all, riffing is a non-compete technique; it is just one more tool in your toolbox. It's not a revolution or an evolution. If you prefer using pen and paper or creating EOD diagrams for sketching out ideas, continue with that.
00:05:06 Riffing can complement those methods. It involves using a single Ruby file, leaning heavily on conventions, and creating runnable code. It's challenging to define, but once you see it in action, it becomes clear.
00:05:38 The goal is to learn about the problem we're working on, including the specifications, and to surface known and unknown unknowns.
00:05:52 If working code emerges, that's a plus, but the primary focus is on learning and figuring things out. This is fundamentally a creative process, tapping into a different side of ourselves.
00:06:30 Instead of being bogged down by traditional file structures and testing in some cases, this technique allows a more flexible approach. I usually have sessions that last between 40 to 60 minutes, making them relatively inexpensive to conduct.
00:07:08 Today, I only have 45 minutes here, so I can't cover everything, but it typically takes about 5 to 10 minutes to reach a flow state.
00:07:37 Let's try a little demo and see how that goes. I'm starting with something simple. In our system, users can favorite other objects.
00:07:53 I usually begin writing out a controller. That might look like a 'favorites' controller. I won’t need a subclass because that won't help me now.
00:08:22 I want to lean on standard RESTful routing as much as possible. I desire to access the current user so they can favorite something.
00:08:37 At this point, I may want to process some parameters to associate it with a user, but I'm unsure of how to proceed. Part of what I like about starting with the controller is that it helps me consider the view side of things.
00:08:56 It also gives me an idea of how it would interact with a model.
00:09:05 I might sketch out a user model, being cautious because I’m dealing with some mirroring issues on the screen.
00:09:25 For the user model, I might add attributes like 'favorites' or ‘favorited items’ but I won't focus on complex associations right now until I gather more design feedback.
00:09:41 This is a method for me to understand the relationships in play without getting distracted by details that may not provide immediate insights.
00:10:17 So, we create a user favorite entity that connects to the user and something else they are favoriting.
00:10:35 I also know there’s something called Signed Global IDs, which Active Job employs in the background to avoid needing to find entries in jobs.
00:10:57 Signed IDs allow you to create a unique, secure signature to your view ID to manage access without repeating unnecessary queries.
00:11:18 We can also scope down the signature to limit its calls.
00:11:33 There's also a limitation where you might want it to only apply to specific objects, like post comments.
00:11:51 So at this point, we've set up a structure around this feature. I'm confident it's a solid initial approach.
00:12:00 However, I'm uncertain about how Signed Global IDs will work exactly, so that becomes my next point of exploration.
00:12:36 It’s important to test these relationships to understand their functionality. If they break at any point, we'll need to rethink our approach.
00:13:01 The next thing I want to focus on is whether users should only be able to favorite certain objects or if we intend to allow them to favorite more items.
00:13:30 This design feedback propels our inquiry into how everything interacts and whether it aligns with our objectives.
00:13:58 Now, I’ll share some benefits I’ve gained from this method. A primary advantage is lower startup costs and friction.
00:14:22 Once I have a shape in mind, I can experiment with it freely, assessing whether I like the direction or want to alter my approach.
00:14:42 Additionally, I eliminate conventional processes like migrations, Git commits, and extensive testing, allowing me to focus on the design.
00:15:02 While these processes are essential and helpful, their drag can hinder us from experimenting with new possibilities.
00:15:39 I find that by removing these concerns, I can move swiftly through ideas and foster creativity.
00:16:06 Since I'm riffing in a single Ruby file, it allows me to examine business logic and ensure the structure holds up as I build.
00:16:28 For me, the experience of riffing helps build my confidence; if an idea proves effective, success energizes me, prompting me to explore further.
00:16:53 Once I have a solid idea in hand, inertia from other projects dissipates, granting me the freedom to experiment with alternative designs.
00:17:15 Exploration enriches my experience per feature, helping me refine my skills in naming and structuring code with diverse approaches.
00:17:58 In the long run, each productive riff builds my expertise, providing leverage that compounds over time.
00:18:26 By actively engaging with these riffing files, I find myself embodying the problem, enhancing recall, and fostering a deeper understanding.
00:19:05 Doing this abruptly links me to the material; it changes how effectively I can communicate problems and propose solutions with my team.
00:19:31 I've also found that this technique produces tangible artifacts in the files, allowing me to share and discuss my thought process with others.
00:20:03 A key aspect of my sessions is to externalize thoughts, avoiding the mental burden of keeping everything in my head.
00:20:34 By working through various elements, both user and user-favorited items, I can better focus on specific questions rather than becoming overwhelmed.
00:21:02 This steady feedback aids understanding and design exploration.
00:21:15 An interesting benefit is that negative emotions encountered during the beginning stages turn into practical indicators.
00:21:39 In the past, feelings of inadequacy toward a project would pop up late in the cycle, making it hard to address them.
00:22:04 Now, if I sense something not aligning, it becomes a useful early warning rather than a late crucial realization.
00:22:41 For instance, I once did a YouTube session on this with a guest. I left that session feeling incompetent.
00:23:09 However, that feedback came early enough for me to focus on improving my abilities rather than regretting time spent on ineffective implementation.
00:23:37 Sometimes, self-doubt reveals uncertainties in specifications, prompting deeper investigations.
00:24:05 Now, let’s shift to potential obstacles you might face while trying out riffing.
00:24:30 For one, you need to know some APIs to successfully put components together. But knowing how to work with belongs_to can provide a strong foundation.
00:25:00 Once you have this base, riffing allows you to expand beyond initial limitations, only facing impediments when you venture into new territory.
00:25:30 I still feel a little disoriented when staring at a blank file; that’s why I embed specifications to help me ease into the task.
00:25:54 It’s pivotal to cling to conventions whenever possible, as they provide guidance that prevents reinventing the wheel.
00:26:38 Staying open to exploration helps ease the pressure of starting anew. The absence of rigorous tests also lets me focus on thoughts without overwhelming detail.
00:27:02 When I hit a roadblock, I often jump to another concept completely, enabling me to backtrack and test different ideas.
00:27:48 Sometimes, I skip back and merely fill in standard framework components that don’t require much thought, resetting my mind for the next round of ideas.
00:28:22 The most important piece of advice I can offer is to continue experimenting and trying new approaches. You’re not confined to careful planning to find solutions.
00:29:03 Instead, play around, see how things unfold, and keep adapting. Back to the live demo, we can discuss what elements of our credits system could be addressed.
00:30:03 The system we're discussing involves teams receiving specific credits each month based on their subscription level, where credits can be spent on different types of reports.
00:30:52 The complication arises with the expiration of credits based on their issuance date, which dictates how they can be used for purchasing reports.
00:31:26 With that in mind, we might consider creating intuitive structures around these credits, focusing on core aspects.
00:31:41 How could we better structure the retrieval and expiration of these credits?
00:31:56 I suggest issuing credits in a way that keeps track of expiration, ensuring that users don't run into hiccups buying reports and using their credits effectively.
00:32:46 As the conversation progresses, we can solidify our ideas and analytics around handling credits.
00:33:02 Let’s consider how different functions can interact when interfacing with these credits.
00:33:26 With any variations on credits implemented, we can start constructing the links on how to interact through reports.
00:33:45 In our closing moments, recognize that collaborating on riffing can amplify everyone’s understanding and rapport, aiding in bridging knowledge gaps.
00:34:31 Finally, for anyone interested in continuing this journey with riffing, you are invited to join me and explore the tools provided during tomorrow's hack day.
00:35:00 This method can facilitate teamwork, help generate ideas, and promote a collaborative environment where creativity thrives.
00:35:36 Thank you for your attention, and I look forward to seeing how you bring riffing into your coding practices.