Jekyll2021-04-22T18:00:29+00:00https://aaron.milam.io/feed.xmlAaron MilamI am a father, a husband, and a software engineer. I love good food, quiet time with my family, and trying new things.Architecture reviews2021-04-22T05:27:00+00:002021-04-22T05:27:00+00:00https://aaron.milam.io/2021/04/22/architecture-reviews<p>Someone recently asked to hear about others’ experiences with architecture design reviews, teams, and processes. I shared one experience from a past job and I think it’s something worth sharing here, too.</p>
<hr />
<h4> </h4>
<p>I was part of implementing an architecture process at one of my past jobs. I’m not sure the way we did it was entirely effective. We built it up over time as perceived needs arose.</p>
<p>At first, we were finding that some database migrations were causing the app to lock up at deploy time because not everyone was aware that, say, adding a NOT NULL column to a large table can do that. So we implemented a review process for those where someone experienced with PG would sign off on migrations.</p>
<p>Later we noticed that sometimes people would add dependencies redundant to other dependencies that they weren’t aware we already had, so we tacked that on to the review process.</p>
<p>As our system became more complex, we decided we needed some people who had an awareness of all the parts and how they fit together. So any new features over some threshold of complexity had to have an architecture document and review by the ADT. That complexity threshold wasn’t well defined - it was more of a list of things to look out for, which did not help with clarity in the process.</p>
<p>A problem with the way we did this is that once a team came up with a design and asked for a review, they’d already put a lot of work into it and it was hard to have them change course when they needed to. It wasted time. And the team wasn’t always clear about what needed review.</p>
<p>I wish we’d done a more collaborative approach where an architect would join the team for their design process rather than have the team come to the architects for review. It would have saved time, feelings, and helped the team learn more effectively about how to make good architectural decisions.</p>
<p>Anyway, the process was okay. But I think that bringing everyone along the process would have been better than inserting a step into their process.</p>Someone recently asked to hear about others’ experiences with architecture design reviews, teams, and processes. I shared one experience from a past job and I think it’s something worth sharing here, too.Career path for a software engineer like me2020-05-25T15:05:00+00:002020-05-25T15:05:00+00:00https://aaron.milam.io/2020/05/25/career-trajectory<p>I call myself a software engineer, but that’s only because that’s a broad term that covers my entire career so far and I believe it will cover my career for some time to come. I started out as a lower level Software Engineer 1, then moved up to levels 2 and 3 at my first company, SEP. At Lessonly, I was a Lead Software Engineer, Director of Engineering, then a Principal Software Engineer. Now at High Alpha, I am again a Principal Software Engineer.</p>
<p>It’s not immediately clear what my responsibilities were in each of those positions just knowing the titles. Such is the way in software engineering. Some companies promote people to a Senior title quickly, while other require some real experience before they start doing that. In some companies a Director may be a functional leader, while in others they are a manager or even a manager of managers.</p>
<p>Because of this, I find it really unhelpful to define what each of those titles means in the industry. But I do think it’s helpful to talk about what they mean in any individual person’s journey so that others can use that as input when they think about where they want to take their careers. So I am doing just that.</p>
<h2 id="software-engineer-1-2--3---sep">Software Engineer 1, 2, & 3 - SEP</h2>
<p>At SEP, this is the path I took. I started out as a Software Engineer 1, then I was later promoted to SE2 and SE3. These were individual contributor positions. As my technical skillset grew, so did my title.</p>
<p>As I grew, I was also given more and more trust. I was still an individual contributor, but on some smaller project I was afforded the responsibility to be the tech lead and project lead. I was able to lay the groundwork for others before they began and I started to act as a mentor to younger engineers.</p>
<p>That level of trust is exactly how I personally think about leveling up in IC roles. As someone proves their level of skill, they can be given more and more trust. As they prove how responsible they are with that trust, they are given the room to grow and to earn more trust.</p>
<h2 id="lead-software-engineer---lessonly">Lead Software Engineer - Lessonly</h2>
<p>I moved on to Lessonly for two reasons: as a means to grow more quickly, and to have the opportunity to own what I worked on. I was craving the ability to learn from what I built and to iterate on it. Working at a product company gave me exactly that. I went in with a goal of building great software and a great team.</p>
<p>I started as the <em>only</em> engineer, with no designers PMs, POs, or any other similar role. This meant I played all of those roles, sharing some of them with my four teammates - the CEO and the directors of CX, Sales, and Marketing. What an immense level of trust. As the software team grew, I became a team lead, mentor, recruiter, and manager.</p>
<p>At a startup that small, one’s role is frequently not very well-defined. Members of a team like that need to define their own roles on the fly, which makes constant clarity and alignment a necessity.</p>
<h2 id="director-of-engineering---lessonly">Director of Engineering - Lessonly</h2>
<p>My role as LSE organically grew into that of Director. At some point, the engineering team grew large enough and I was managing a department, which made the title change seem like an obvious step.</p>
<p>This is where I stumbled the most. I had never been a manager before and I really enjoyed my work as an engineer. I held onto the roles of an individual contributor, manager, mentor, recruiter, project manager, and more. While these are all roles that a Director of Engineering <em>can</em> play, one person should not play <em>all</em> of them. I did not seek enough help and it became too much for me.</p>
<h2 id="principal-software-engineer---lessonly">Principal Software Engineer - Lessonly</h2>
<p>I had a conversation with the CEO at Lessonly during a time of change where we talked about all of my responsibilities. I felt the most stress from being a people manager, so I asked to make a lateral move to Principal Software Engineer. This was a position of technical leadership, mentorship, and even individual contribution, but not of management. I was able to manage my work load almost immediately.</p>
<p>This role shifted over the course of a couple years. I acquired an excellent mentor in my new direct manager. He helped me work through my experiences and feelings on being a manager. I like to think I helped him a bit, too. I slowly shifted and balanced my responsibilities to keep from overloading my plate too much. I became a manager again and acted as an engineering leader while contributing mostly to high-level architectural design and implementation.</p>
<p>At this point, I realized that I had fulfilled what I had originally come to Lessonly to do: to build an excellent product and an excellent team behind it. I was and am still proud of the team still making Lessonly better all the time, but I realized my passion isn’t in scaling large teams. It’s building teams from scratch and helping those on the teams grow in their own careers.</p>
<h2 id="principal-software-engineer---high-alpha">Principal Software Engineer - High Alpha</h2>
<p>I made a move to High Alpha, keeping the title Principal Software Engineer. High Alpha builds companies, and I was brought on to help build the software at the earliest stage of those companies, help build their teams, and to build a community among the engineers at those companies. My role at High Alpha is that of a mentor, but not a manager.</p>
<p>While I don’t get to own the products I build, I am building the foundation for those products and those teams while I figure out the next step in my career.</p>
<h2 id="more-to-come">More to come</h2>
<p>I am nowhere near the end of my career. I hope to continue building teams, helping others figure out their own trajectories, and building great software that people love. And it is my hope that by recounting my own path may help you plan your own.</p>
<hr />
<p><em>NOTE: I realize that I have been incredibly lucky and privileged. After all, I am a straight, white, cisgender man in an industry dominated by exactly that kind of person. I didn’t write this as a guide to follow, or as a path that anybody should emulate. I only mean to share my experience in hopes that others would do the same so that we can all learn from each other’s experiences.</em></p>I call myself a software engineer, but that’s only because that’s a broad term that covers my entire career so far and I believe it will cover my career for some time to come. I started out as a lower level Software Engineer 1, then moved up to levels 2 and 3 at my first company, SEP. At Lessonly, I was a Lead Software Engineer, Director of Engineering, then a Principal Software Engineer. Now at High Alpha, I am again a Principal Software Engineer.My Hacker Muscle Has Atrophied2019-03-13T02:15:00+00:002019-03-13T02:15:00+00:00https://aaron.milam.io/2019/03/13/my-hack-muscle-has-atrophied<p>I have found myself building a new web app in my spare time. I have a need which I am trying to solve - that’s how these things start, right? It’s been a while since I started something in my own time that I was excited about, so it feels good to be building something outside of work.</p>
<h3 id="discovery">Discovery</h3>
<p>I started by identifying what I need a tool to do to solve my problem. I asked myself: what am I trying to do that is difficult right now? What would make that easier?</p>
<p>This line of thinking ended up with me creating an affinity map of the things I would like my tool to do. It’s pretty extensive. It includes solving my basic problem and some really neat tangential features. I identified the area that is most important to me and I thought through a data model that would allow me to store the data I need to build a tool.</p>
<h3 id="engineering">Engineering</h3>
<p>I began building a Rails app (it’s what I know best at the moment). I knew what I needed to start with: a simple Rails app with a Postgres database and <a href="https://github.com/thoughtbot/clearance">Clearance</a> for easy user management. And I did it with Rails 6.0.0.beta2, because why not live on the edge? Then I began building my tool.</p>
<p>The code is beautiful, really. The controller actions are short. The business logic lives in service objects. The code is DRY and accommodates multiple similarly-behaving integrations. But I still don’t yet have something I can test in the real world.</p>
<p>As I’m writing my code, I’m realizing something. I’m not hacking. Instead, I’m thinking through the architecture. I’m considering how I want everything to work together in the future. <strong>I am slowing myself down.</strong></p>
<h3 id="being-lean">Being Lean</h3>
<p>One of the more important ideas from Lean is that you should try something quick and see how it does before building something elaborate. If you build the elaborate thing first and end up realizing that what you built doesn’t actually solve the problem you’re trying to solve, then you’re stuck with having spent a lot of time on something that doesn’t work <em>and</em> you’re stuck with the large task of changing that elaborate thing. When you build something small first, you can test how that does and find out what needs to improve without having wasted any effort.</p>
<p>I’ve been in an architecture role at my job for a while now. We have a relatively mature ecosystem where everything needs to work both for our customers and for the engineers. We need a well thought-out way of doing things to make sure that our application’s complexities are easy enough to follow, are performant, make sense to our end users, and that they just work. I have been in this mindset for so long that I’m finding it difficult to go back to hacking.</p>
<h3 id="evolution">Evolution</h3>
<p>At my previous job, quickly hacking something together was frequently a useful skill. I could whip up a project and have something to show for it in a few hours’ time. I could get some feedback and iterate before the day was over. This was my biggest strength.</p>
<p>That skill was important at my current job at Lessonly when I first started. When I joined, we were still an early stage startup, so we were trying things left and right to see what would stick and what would sell. When I first started, the transition was easy because I was doing the same kind of work - just in a single project instead of many.</p>
<p>As time went on, we hired more engineers and my role began to shift. I became a manager for a while. We as a team realized we needed to standardize how we work. The application became more complex, so we needed to build an architecture that made sense. And then I shifted into a role overseeing that architecture.</p>
<p>Now I spend my days mitigating risk through how we build software. It’s my job to make sure that everything is built in a way that makes sense now and is going to continue making sense for the foreseeable future. I have to predict the problems we will have and make sure we are able to prevent them. This is my new <em>modus operandi</em>.</p>
<h3 id="re-learning-to-hack">Re-Learning to Hack</h3>
<p>I’m glad I realized what is going on. The most effective thing I can do right now is to get something working so I can try it out. Otherwise, I’m building toward a dream that I hope is as awesome in reality as I’m imagining.</p>
<p>It’s better to start in the wild west. Sure, I can write beautiful code, but what use is it if I’m not positive it’s going to live for more than one iteration? The best thing I can do is hack together something that works and try it out. And if I like it, I can build on it. And refactor it to my heart’s content.</p>
<p>I hope I build something neat that I can share with you all some day soon.</p>I have found myself building a new web app in my spare time. I have a need which I am trying to solve - that’s how these things start, right? It’s been a while since I started something in my own time that I was excited about, so it feels good to be building something outside of work.What Is a Software Architect?2018-10-18T01:20:00+00:002018-10-18T01:20:00+00:00https://aaron.milam.io/2018/10/18/what-is-a-software-architect<p>I have been thinking a lot about what it means to be a Software Architect, primarily because I am working to define that role at Lessonly. What does an architect do that is different from other engineers on the team? What do they <em>not</em> do? What skills do they need to have and how do they use them?</p>
<h2 id="its-a-way-of-thinking">It’s a way of thinking</h2>
<p>Architecture, to oversimplify it, is a way of thinking. Architects are able to think in systems. They think about how systems are defined, how they interact with each other, how they are structured and organized. Non-architects sweat the details within the systems while architects think a level above that. Both of these mindsets are absolutely essential on a software team.</p>
<h2 id="interactions-between-systems">Interactions between systems</h2>
<p>Any software application comprises several parts, whether they are disparate services, modular components, or layers within a single application. Following the principles of <a href="https://en.wikipedia.org/wiki/SOLID">SOLID</a>, the parts should not rely on each other directly; they should only rely on each other’s contracts. That is, each component should define how it communicates with other components, and the components should communicate with each other only along their defined APIs.</p>
<p>An architect might think about those interfaces, how they are defined, how they might affect the components in the future, how they might be used, and how the underlying systems might need to change in the future. They understand the current needs of each system and consider their possible futures so that they can design the APIs to meet those needs.</p>
<h2 id="considering-stakeholders-needs">Considering stakeholders’ needs</h2>
<p>An architect considers the needs not only of software systems, but also of the business and of those who interact with the software. For example, a SaaS startup is likely to need to optimize for the ability to develop and deploy software quickly, while a more mature SaaS company probably needs to think more about security, data privacy, and performance to keep their larger customers feeling safe.</p>
<p>The startup is more likely to keep its systems consolidated so that developers can write entire features quickly. The mature company likely needs to keep components separated so that they can secure and optimize each of them independently.</p>
<h2 id="defining-standards">Defining standards</h2>
<p>The kinds of decisions architects make tend to be the kind that define how the software is built. They create patterns and standards such that if anything needed to change, it would be expensive to do so because those patterns and standards affect <em>everything</em>. So as the architect considers the shape of the software they are designing, they must think about how to build it in a way that considers how parts of it could change without affecting other pieces in order to minimize the impact of the change.</p>
<p>Still, since some of the work done by architects is to design the interfaces between systems, and the patterns that permeate through infrastructure and applications, it’s often difficult to keep the impact of change minimal. This is why it’s so important for architects to be able to consider present <em>and</em> future needs of all the stakeholders involved.</p>
<h2 id="bringing-it-all-together">Bringing it all together</h2>
<p>Software Architecture is systems-level thinking. Architects define how the software is built. And they must consider the present and possible future needs of all stakeholders.</p>I have been thinking a lot about what it means to be a Software Architect, primarily because I am working to define that role at Lessonly. What does an architect do that is different from other engineers on the team? What do they not do? What skills do they need to have and how do they use them?Impostor Syndrome2018-10-18T00:54:00+00:002018-10-18T00:54:00+00:00https://aaron.milam.io/2018/10/18/impostor-syndrome<p>I have heard the term “Impostor Syndrome” thrown around a lot lately to the point where I don’t believe its meaning is truly agreed upon. I know I have a bit of impostor syndrome going on, but now it feels like saying that is supposed to be a badge of honor. So now I prefer to think of it for what it really is: self-doubt.</p>
<p>I am at a point in my career where people look up to me because of the impact I’ve made. It’s hard to write that because I’m thinking to myself “why would people look up to me? I’m no different from anybody else.” From what I’ve heard, this is a common feeling among software engineers who present or want to present at conferences, those who write or want to write blogs, and those with higher positions at their companies.</p>
<p>The advice I commonly hear is something along the lines of:</p>
<blockquote>
<p>You have <em>something</em> you know well - even if you’re not a leading expert on it, you can still teach others.</p>
</blockquote>
<p>This is true! And if you are afforded an opportunity, you likely have what it takes to accept that opportunity. I have doubted (and still frequently do) whether my thoughts and ideas are truly valuable. But when I begin to think that way, I remember the idea above and recognize my feeling for what it is.</p>
<p>So now I choose not to think of how I feel as impostor syndrome, but as self-doubt. When I use that term, I quickly convince myself that I can overcome it. And I do.</p>I have heard the term “Impostor Syndrome” thrown around a lot lately to the point where I don’t believe its meaning is truly agreed upon. I know I have a bit of impostor syndrome going on, but now it feels like saying that is supposed to be a badge of honor. So now I prefer to think of it for what it really is: self-doubt.I Wrote a README2018-09-19T00:55:15+00:002018-09-19T00:55:15+00:00https://aaron.milam.io/2018/09/19/i-wrote-a-readme<p>Some people call them Manager Readmes. I’m calling mine simply, README. It’s about me. As a manager, as a coworker, as a direct report, as a human. You can read it right <a href="/readme/">here</a>.</p>
<p>I believe this README can be helpful to those I work with, but more importantly it is helpful to me for introspection. As I wrote that page, it forced me to think about what I am like. It forced me to think about how I can be a better person and coworker.</p>
<p>I plan to update my README frequently when I think about it. Hopefully I will update it when I find something new to focus on improving about myself. Hopefully I will update it when I have done enough to improve in areas that I don’t think I need to focus on them anymore.</p>
<p>So feel free to read my README. You don’t have to if you don’t want to. But I welcome your feedback!</p>Some people call them Manager Readmes. I’m calling mine simply, README. It’s about me. As a manager, as a coworker, as a direct report, as a human. You can read it right here.On Delegating2018-08-22T12:33:15+00:002018-08-22T12:33:15+00:00https://aaron.milam.io/self/2018/08/22/on-delegating<p>Over the last few years I’ve grown as a leader. I’ve learned that as I grow in my career and as I grow the team around me, the work load does not get easier - it gets much heavier. Of course, delegating is a skill that helps with the work load, but, for me at least, there are several barriers to get through before becoming effective at it.</p>
<p>I started at my current job at Lessonly as the Lead Engineer - that is, I was the <em>only</em> engineer. At this point, the work load was relatively easy to manage. I worked directly with the heads of the other departments (the one-person departments) to prioritize what needed to be done, technically. And the needs were relatively simple as we were feeling out our market’s needs.</p>
<p>Over time, we grew the engineering team and I slowly added more hats to my head - architect, manager, project manager, devops, and anything else the engineering team needed, all while still being a developer. As the team grew, the work load grew. And as the work load grew, I needed to learn how to spread my responsibilities across the team to keep from disappointing my teammates.</p>
<p>When I didn’t delegate effectively and I spread myself too thin, I became ineffective at the things I was trying to do. I was switching contexts constantly, letting things that others were relying on me for slip, forgetting to check in on things that I needed to check in on. And worst of all, I didn’t perform half of my respsonsibilities as a manager of people. I think I did a decent job of making sure my teammates had what they needed in the moment, but I’m sure I wasn’t effective with helping them grow.</p>
<p>During that experience, I ran into three primary barriers to being effective at delegating: trust in my teammates, being okay with adding to my teammates’ work load, and sharing my knowledge so that my teammates are able to take on my responsibilities.</p>
<h3 id="trusting-my-teammates">Trusting my teammates</h3>
<p>If I’m going to ask my teammates to help me with my responsibilities, I need to trust them. If I don’t, then I’m certainly not going to trust them with taking care of something I need to deliver for the company.</p>
<p>Fortunately, this comes relatively easily with my current team, as I am surrounded by a lot of really smart people. When they agree to do something, I know that they will deliver and without keeping anybody waiting. And it’s not out of fear for their jobs or anything - they’re just good people.</p>
<p>At Lessonly, we value the three attributes of the <em>Ideal Team Player</em> as defined by Patrick Lencioni. We hire people who are humble, hungry, and people smart. It’s those qualities that make it easy to trust my team.</p>
<h3 id="being-okay-with-adding-to-my-teammates-work-load">Being okay with adding to my teammates’ work load</h3>
<p>This one is a bit harder. I like my teammates. I know they’re all busy. Shouldn’t I avoid adding more to their plates so that they can focus on whatever they’re currently doing?</p>
<p>Here’s the thing: they’re good people. They’re smart. They want to make sure the team succeeds. They want to help. They can tell me when they have too much on their plate.</p>
<p>I just have to keep this in mind. It’s tough, but the more I do it, the more I realize that my teammates actually <em>want</em> the added responsibility. Think about that. If I don’t allow others to take on some of my respsonsibilities, I’m denying them the opportunity to learn new things and grow in their own careers. Holy crap, it’s not just about me.</p>
<h3 id="getting-the-knowledge-out-of-my-head">Getting the knowledge out of my head</h3>
<p>Okay, so at this point I’ve decided that it’s okay to pawn off some of what I do to others. But now, I have a lot of knowledge about all those responsibilities stored neatly in my own brain where nobody else can get at it. This is where I struggle currently.</p>
<p>In my position, I make a bunch of decisions about how things should work, including how our web hosting is organized, how data flows between systems, and how we resolve certain kinds of customer requests. I’ve been offloading these things more and more, but it seems like every time I do, I find that I haven’t documented <em>anything</em>.</p>
<p>Luckily, I work at a company that builds software for this very kind of knowledge sharing. I build a lesson in our internal Lessonly account documenting the thing I know so that others can discover it (and share it directly with whomever I’m asking to take it on) and so that I’m not the only one who knows how to do it.</p>
<p>The thing I’m working on now is proactive documentation. Sure, I might be the only one doing some things now, but a lot could happen. What happens if I don’t do a thing for a long time and I forget how I did it? What if I’m on vacation and somebody else needs to take care of it? What if I’m just too busy one day to do the thing, write documentation about it, or even explain it to someone else?</p>
<p>So now, as I discover things I know that nobody else knows, I am trying to document those things proactively before anybody needs to know those things.</p>
<h2 id="and-so">And so…</h2>
<p>Delegating is hard to do effectively. It’s important for a lot of reasons. And I am working on doing it better.</p>Over the last few years I’ve grown as a leader. I’ve learned that as I grow in my career and as I grow the team around me, the work load does not get easier - it gets much heavier. Of course, delegating is a skill that helps with the work load, but, for me at least, there are several barriers to get through before becoming effective at it.Best Steak I Ever Had2018-08-18T15:15:59+00:002018-08-18T15:15:59+00:00https://aaron.milam.io/food/2018/08/18/best-steak-i-ever-had<p>Just the other day, I ate the best steak I’ve ever had. It was a $10 ribeye I made myself using a sous-vide cooker. I seasoned it with salt, pepper, and rosemary, vacuum sealed it and froze it when I bought the meat. I took it right from the freezer and cooked at 132.5° for about and hour and a half before grilling it at high heat for a couple minutes on each side. Paired with a sweet potato with red onion, it was an amazing meal.</p>
<p>Yep, that’s all this post is about, but I felt it was important to share.</p>Just the other day, I ate the best steak I’ve ever had. It was a $10 ribeye I made myself using a sous-vide cooker. I seasoned it with salt, pepper, and rosemary, vacuum sealed it and froze it when I bought the meat. I took it right from the freezer and cooked at 132.5° for about and hour and a half before grilling it at high heat for a couple minutes on each side. Paired with a sweet potato with red onion, it was an amazing meal.Use a return_url with omniauth2015-03-24T19:55:54+00:002015-03-24T19:55:54+00:00https://aaron.milam.io/2015/03/24/use-a-return-url-with-omniauth<p>I’ve been working on implementing single sign on in Lessonly (a Rails 4.2 app), specifically with SAML (because that’s what the clients need). <a href="https://github.com/PracticallyGreen/omniauth-saml">Omniauth</a> has been making it fairly easy to do, which has been great.</p>
<p>However, I had need of keeping track of a <code class="language-plaintext highlighter-rouge">return_url</code>. This can get weird because with SSO, the service provider (SP) sends the user to a different place on the web, the identity provider (IdP), which then sends the user back to your SP. Keeping track of a <code class="language-plaintext highlighter-rouge">return_url</code> is not reliable through these requests.</p>
<p>There is one thing that I tend not to think about when developing Rails apps - the session. In general, I believe that using the session is a bad idea. The big exception being that I use it to keep track of the current logged in user.</p>
<p>Since I don’t generally use the session, this option escaped my mind for a while when I was trying to figure out this particular problem. However, it works very well here.</p>
<p>Omniauth allows us to define a setup action which runs before the authentication request is sent:</p>
<div class="language-rb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># config/initializers/omniauth.rb</span>
<span class="n">provider</span> <span class="ss">:saml</span><span class="p">,</span> <span class="ss">setup: </span><span class="kp">true</span>
<span class="c1"># config/routes.rb</span>
<span class="n">get</span> <span class="s2">"/auth/:provider/setup"</span> <span class="o">=></span> <span class="s2">"sessions#sso_setup"</span>
<span class="c1"># controllers/sessions_controller.rb</span>
<span class="k">def</span> <span class="nf">sso_setup</span>
<span class="n">session</span><span class="p">[</span><span class="ss">:sso_return_url</span><span class="p">]</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="ss">:return_url</span><span class="p">]</span> <span class="k">if</span> <span class="n">params</span><span class="p">[</span><span class="ss">:return_url</span><span class="p">]</span>
<span class="c1"># additional setup...</span>
<span class="k">end</span>
</code></pre></div></div>
<p>We can then use the return_url in the session upon authentication:</p>
<div class="language-rb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># config/routes.rb</span>
<span class="n">post</span> <span class="s2">"/auth/:provider/callback"</span> <span class="o">=></span> <span class="s2">"sessions#sso"</span><span class="p">,</span> <span class="ss">as: :sso_callback</span>
<span class="c1"># controllers/sessions_controller.rb</span>
<span class="k">def</span> <span class="nf">sso</span>
<span class="c1"># authenticate...</span>
<span class="n">redirect_to</span> <span class="n">sessions</span><span class="p">[</span><span class="ss">:return_url</span><span class="p">]</span>
<span class="k">end</span>
</code></pre></div></div>
<p>Just as simple as that.</p>I’ve been working on implementing single sign on in Lessonly (a Rails 4.2 app), specifically with SAML (because that’s what the clients need). Omniauth has been making it fairly easy to do, which has been great.Rails, Rspec, and testing controllers with the same name2014-09-11T20:53:39+00:002014-09-11T20:53:39+00:00https://aaron.milam.io/2014/09/11/rails-rspec-testing-controllers-with-same-name<p>It’s important to write tests for your code.</p>
<p>However, I was trying to write some tests for a pair of rails controllers with the same name, but different modules. The controllers look something like this:</p>
<div class="language-rb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># app/controllers/my_controller.rb</span>
<span class="k">class</span> <span class="nc">MyController</span> <span class="o"><</span> <span class="no">ApplicationController</span>
<span class="o">...</span>
<span class="k">end</span>
<span class="c1"># app/controllers/subsection/my_controller.rb</span>
<span class="k">class</span> <span class="nc">Subsection::MyController</span> <span class="o"><</span> <span class="no">Subsection</span><span class="o">::</span><span class="no">ApplicationController</span>
<span class="o">...</span>
<span class="k">end</span>
</code></pre></div></div>
<p>Then I wrote Rspec tests for each, which all work when run one file at a time:</p>
<div class="language-rb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># spec/controllers/my_controller_spec.rb</span>
<span class="nb">require</span> <span class="s1">'spec_helper'</span>
<span class="n">describe</span> <span class="no">MyController</span> <span class="k">do</span>
<span class="o">...</span>
<span class="k">end</span>
<span class="c1"># spec/controllers/subsection/my_controller_spec.rb</span>
<span class="nb">require</span> <span class="s1">'spec_helper'</span>
<span class="n">describe</span> <span class="no">Subsection</span><span class="o">::</span><span class="no">MyController</span> <span class="k">do</span>
<span class="o">...</span>
<span class="k">end</span>
</code></pre></div></div>
<p>However, when I ran all the tests at once using ‘$ rake spec’, the tests for Subsection::MyController
always tried to use the MyController at the base level for the controller, which led to an error like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ActionController::UrlGenerationError:
No route matches {:action=>"the_action", :controller=>"my_controller", :id=>"123"}
</code></pre></div></div>
<p>I finally found the solution after chasing the wrong symptoms. I can’t explain it better than <a href="http://stackoverflow.com/a/19028366/251543">this guy</a>. In short, require the class you’re testing at the top of your test files to ensure the right class is being loaded:</p>
<div class="language-rb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># spec/controllers/my_controller_spec.rb</span>
<span class="nb">require</span> <span class="s1">'my_controller'</span>
<span class="nb">require</span> <span class="s1">'spec_helper'</span>
<span class="n">describe</span> <span class="no">MyController</span> <span class="k">do</span>
<span class="o">...</span>
<span class="k">end</span>
<span class="c1"># spec/controllers/subsection/my_controller_spec.rb</span>
<span class="nb">require</span> <span class="s1">'subsection/my_controller'</span>
<span class="nb">require</span> <span class="s1">'spec_helper'</span>
<span class="n">describe</span> <span class="no">Subsection</span><span class="o">::</span><span class="no">MyController</span> <span class="k">do</span>
<span class="o">...</span>
<span class="k">end</span>
</code></pre></div></div>It’s important to write tests for your code.