Building a Rails App: A Journey of Breaking and Fixing Code
*Mini Lesson in dependent: :destroy Included
For my third project at Flatiron as a Software Engineering Student, I built a Ruby on Rails web-application. Prior to this project I had created a Ruby command-line API and used the Sinatra framework to build a basic web-application. The Rails web app would be much more complex than the Sinatra app, but the first two projects were valuable stepping stones in setting me up for success. For anyone learning to code, I can share a few pieces of advice and takeaways from this particular project:
- Spend time planning
- Be comfortable in a state of things being broken
- Try, and then try it again (read the documentation)
- Soak up that “I fixed it!!” feeling
Getting a jump on this project in terms of planning was key. I spent time asking myself what was the overall goal of my project and why, how I wanted to structure my database, what my models and relationships would be, and what queries I would want to use down the road. I wanted to have a solid idea of who my user was and what their goal was, but there also needed to be a reason. My notes looked like this:
- As a <user>
- I want <share, discuss, and study interview questions for software engineering related jobs>
- So that <I can feel prepared, set myself up for success, and land my desired job>
In terms of designing my models and relationships, I knew it was important to structure my database in a way that could help meet the goals of my project and allow me to design it so it would function in certain ways. For example, I knew I wanted my interview questions to be organized by category and thus knew that it would be best to make category it’s own model as opposed to an attribute on the interview questions table.
No matter how much planning goes into a project, when coding, I think there will be a continuous cycle of your code breaking, trying to fix it, and re-trying. But when it is fixed, oh what a wonderful feeling! I had planned out all my relationships and was testing everything out. It seemed to work beautifully. I seeded my categories, created my users, posted some interview questions, and made some comments.
Then, I tried to clean up my app by deleting a user. No dice.
After some googling (ya gotta love and master this tool), I found a fix, but it took more than one try before it took.
Let’s me take a moment to share how these two words of code are a fantastic way to handle cascading destroys. Here is what I learned through reading the documentation (https://guides.rubyonrails.org/association_basics.html) and a number of various google searches on the subject.
:dependent is an option available to us from the belogs_to associations, it delegates what happens to the associated objects when the parent object is destroyed. Adding :destroy causes all the associated objects to be destroyed when the object selected is destroyed. So if an interview question belongs to a user and a category, but also has many comments, there is a cascade of associations happening. If I want to delete a user and want the cascade of destroy to run through all the associations to the end of the line, I need to specify :dependent :destroy. There are other options to add after :dependent, such as :delete, delete_ all, nullify, but this becomes a blog for another day otherwise this mini lesson will not be so mini. Bottom line, because no one wants orphaned records in the database and to make sure the cascade of destroying objects isn’t interrupted by a remaining association constraint, make sure dependent: :destroy is added to all the has_many associations. I missed one association and I kept getting the same rollback error. Finally I added this two-word power punch of code in all the right places and BAM, bye bye user.
I basked in the feeling of fixing my code like being in a warm luxurious bath. I had to soak it up because I knew something else would probably be broken soon. Coding is a journey of planning, breaking, researching, and fixing. Well there is a little more to it, but that is what stands out from my experience of building a Rail app.