Reflections on the Rails Portfolio Project
My daughter is almost two and one of her favorite things to do is see how much food she can fit into her mouth at one time. She will take a fistful of sweet potatoes big enough for a Paul Bunyan type and try to eat it as if it was a normal bite. At almost every meal I find myself saying, “Hey…that’s a big bite.” I want her to only take what she can handle, not overreach for these gargantuan chunks.
Reading through the project description, one line in particular stood out to me: “make no little plans.” Before sitting down to begin this project, I set out a goal to stretch myself beyond what I had learned through the curriculum. I didn’t want to just meet the requirements, I wanted to build something that went far beyond them. While I wouldn’t change anything about this learning experience, I can say, without exaggeration, that this was one of the most difficult tasks I’ve ever set out for myself…and I have a toddler.
I wanted to build an application that managed the general workflow associated with a Talent Agency or Management Office. One of the most consistent things I’ve noticed as a working actor in NYC is how many offices seem disorganized and haphazard. Creating something that would serve to tidy up some of the mess of the industry seemed like a project I could get behind.
I also liked the idea of an Agency having an account with many users. On top of that, I wanted the ability to have multiple agencies, each with their own users. Since the data generated by the app could potentially be sensitive, it seemed important that agency’s users would only have access to their own data. Through several hours of research, I discovered that developers refer to this idea as “multi-tenancy.” And without any idea of how this would or even COULD happen, I decided my app would incorporate multi-tenancy.
Before opening my laptop, I knew I wanted to understand exactly what kind of models I would need and what their relationships would be between each other. I grabbed a notebook and started drawing the relationship diagrams. When it came to accounts, I broke it down as follows:
AGENCY - An agency would serve as the application’s tenant, meaning that all data associated with that agency would only be within that specific agency’s purview. The agency itself would have many:
USERS - A user model needed to represent that actual employee within an agency. Users would have to belong to the agency in order to sign up, as a User without an Agency would have access to zero data. At the same time, I knew signing up for a User account with an Agency did not necessarily mean that a user should have access to the agency’s data. Users would need to be confirmed somehow. This meant that Users would have certain roles, Admin, Confirmed, and Unconfirmed. This was another instance of not knowing exactly how I would implement functionality, but being certain I would need it.
So what data would these Users be CRUDing? I wanted my model objects to resemble what is dealt with most often at a real Talent Agency. The models I needed include:
ACTOR CASTING OFFICE PROJECT APPOINTMENT (audition) BOOKING
I was actually terrified opening up my laptop, I already felt as if I had bit off more than I could chew. My head was spinning trying to imagine all the attributes these models would have and how they would interact. I found a great website, dbdiagram.io, which helped me to organize all this information in a way that was easy to visualize. Taking the time to map out all of my relationships was invaluable.
After printing out all the diagrams, I felt confident I could start building my models in my new rails app. For the most part, this was pain-free. Initially…
One of the requirements of the project is that there has to be a standard authentication system for logging in/out. I had done this several times throughout the curriculum, so it wasn’t that difficult to get an authentication flow working.
I should have read all the requirements 1000 times before starting to code.
So what had happened was …I had all of my models and relationships working as they should, and then I started trying to implement other requirements of the project, mainly the Devise gem and a gem I found for multi-tenant apps called, Acts as Tenant Since I had already built my authentication and a very rough version of multi-tenancy, these gems did not function as they were intended. I spent the next several days untangling my code and getting it out of the way of these gems so they could do their job.
If there was one piece of advice I would give to myself before starting this project again, it would be to implement your login system first before building out the rest of the application. While it wasn’t wasted time, I spent so many hours frustrated and feeling like I was actually making negative progress. Yes, it is a learning process, but I had made it so much more difficult than it needed to be and was paying the price. On top of everything, I felt like I was asking so much of my wife and daughter while struggling through this. It took 100% of my brain power.
After what felt like years, I was able to get my head above water and felt like I had some momentum again. The multi-tenancy was functioning as intended and Devise had been integrated into my application. The next few days were spent building out controller logic and routes. I also built methods to allow Admin Users to confirm new Users and make them confirmed Users (I later realized so much of this functionality is included in a very user-friendly way with Devise.) It was begining to look like I might finish this damn thing after all…
But wait! I still have time to make things harder on myself!
I had used Bootstrap in my previous portfolio project, albeit minimally. Since then, I have seen a few other applications that utilized Bootstrap and wondered why, stylistically, they looked more polished. I read most of the documentation and found myself wanting to implement so much of it. This was another situation where I had to fit what I had already created into something I didn’t fully understand. It added another couple of days onto the project, but I grew more comfortable with many Bootstrap components and brought them into my project, giving it a much cleaner look and feel. It looked less like a project and more like an application. This made me proud.
After hours of refactoring, moving logic from the views and controllers into the models, I could feel myself approaching the homestretch. I met almost all of the requirements except one.
“Your authentication system must also allow login from some other service. Facebook, Twitter, Foursquare, Github, etc…”
Shouldn’t be too tricky, I had done this twice during the curriculum with OmniAuth. I figured I would follow the instructions for OmniAuth Facebook from Github, and call it a day.
How. Wrong. I. Was.
This was the biggest struggle I had in the entirety of the project. Not only did I want my Users to have more than just an email to be registered, but I also had a multi-tenant app which made utilizing Omniauth with Facebook incredibly challenging. In the curriculum there is a line that the point of learning Omniauth is “not to waste six hours fighting with the Facebook developer interface.” Oh, how I wish I had just wasted six hours. I wasted DAYS with the Facebook developer interface. So many potential solutions for my problem involved things I had little to no experience with such as Javascript and their Facebook SDK. So many times I thought I was close to a solution, only to have everything fall apart. There was one particular day where I thought I had a Eureka moment, “OHHHHH! THEY SAY YOU HAVE TO HAVE A PRIVACY POLICY URL!” I rushed to create a Privacy Policy, only to realize that had absolutely nothing to do with why my Facebook login says “invalid App ID”. I was ready to just give up and tell my evaluator I couldn’t do that component and see how things played out. In one last ditch effort to get things up and running, I re-did all the steps I felt were appropriate for my application and for some reason I DON’T UNDERSTAND…it worked. How fun.
The long and short of it is, this was a major challenge but has provided me with an incredible sense of accomplishment and resourcefulness. In moments where I would normally turn to the Learn.co curriculum for answers, I found myself reading documentation specific to my problem from the source, reaching out to friends with development jobs, reading stackoverflow questions and browsing random applications for any piece of code that seemed to be a missing puzzle piece. It was learning at its most intense.
I am so proud of what I created. I am sure an experienced app developer would have many critiques with my code and a UX designer might tear me to shreds, but they would still be looking at a fully functional application which does exactly what I intended it to do.
How you like them apples?