Flatiron Phase 5 Blog
Published: 2023-05-17 23:25:36

Working on my Phase 5 Capstone Project, I’ve felt a heady mix of emotions. Throughout the Flatiron Software Engineering Flex program, I’ve continually put off thinking about the end of the program or the next steps that come after graduation, choosing instead to focus on whatever work was right in front of me. Now, working on my final project for the program and getting (hopefully) closer and closer to graduating with each bug fixed and feature added, I can’t ignore the bittersweet feelings that come with nearing the end of something that I’ve worked hard at. 
I’ve also sensed a bit of a shift in my thinking for this project when compared to my projects for previous phases. Whereas before I focused almost entirely on functionality and best practices, I find myself with this project thinking more and more about user experience and the precedents set by apps that are similar to mine. For example, my app functions a bit like a social media site, with different profiles people can visit. To keep things RESTful, the structure of a user’s profile url looks like, “/users/:id”, but what if someone wanted to visit their friend’s profile and didn’t know what their user id was? Wouldn’t it make more sense on the user side of things if the url looked more like “/users/:username”? This kind of thinking has led me down some real rabbit holes. It can be tough to decide when and how to prioritize user experience or developer convention, especially when I’m so new to all of this and haven’t really gotten a chance to peek behind the curtain at how these decisions are made. 
For now, though, I’ve been happy to focus on those elements of user experience that I can upgrade from previous projects without compromising existing conventions. For this project, I decided to incorporate Active Storage into my project to handle storing and attaching images to user posts. My previous projects required users to submit image urls if they wanted to upload images. This worked fine and it was nice and simple to store an image url as a string, but it put the burden of sourcing or hosting images onto the user, adding steps into making a post that complicated the whole process. This time around my project was very image focused, so I wanted to make posting images as easy and intuitive as possible. And Active Storage allowed me to do just that!
```
create_table "active_storage_attachments", force: :cascade do |t|
   t.string "name", null: false
   t.string "record_type", null: false
   t.bigint "record_id", null: false
   t.bigint "blob_id", null: false
   t.datetime "created_at", null: false
   t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
   t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
 end


 create_table "active_storage_blobs", force: :cascade do |t|
   t.string "key", null: false
   t.string "filename", null: false
   t.string "content_type"
   t.text "metadata"
   t.string "service_name", null: false
   t.bigint "byte_size", null: false
   t.string "checksum"
   t.datetime "created_at", null: false
   t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
 end


 create_table "active_storage_variant_records", force: :cascade do |t|
   t.bigint "blob_id", null: false
   t.string "variation_digest", null: false
   t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
 end
```
The Active Storage tables in my schema file. Installing Active Storage created a migration that sets up these three tables: active_storage_blobs, which stores data about the attachments, active_storage_attachments, which acts as a join table to connect blobs to models, and active_storage_variant_records, which tracks variants if variant tracking is enabled (I haven’t really used this one so far). More can be read about Active Storage [here](https://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files).

My app is a sort of digital sketchbook/social media site geared towards artists posting the studies they make to hone their technical skills. Using Active Storage opens up all kinds of functionality that makes posting images with a given study much more straightforward for users.
```
params[:images_to_delete]&.each do |image_id|
        study.images.find_by(id: image_id).purge
       end

```
Here’s an excerpt from my Update method in my Studies controller. Using the Active Storage purge method, I’m able to remove any images whose id has been passed in an array with params from the study post being edited. This deletes the associated blob and image file from the database while keeping the study intact, all thanks to Active Storage!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugoo61bidqoll035ovfa.png)
My simple little post submission form. Note the Choose Files input option for uploading images from the user’s device!

It feels very strange to be finishing this stage of my programming journey. For so long, I’ve been focused on just learning what I can and getting things to work in my projects, but now with this project I feel I’ve expanded my goals and thought processes to include investigations of my own experiences using various apps. I’m also glad I’ve gotten the chance to incorporate art into my capstone project. Transitioning from art to a career in tech has been very exciting overall, but it’s been a bit sad too to feel like I’m leaving my artistic roots behind. Working on this app has shown me that my art and tech journeys can continue forward together. This project has even gotten me to start painting again! Going forward, I’m eager to see how my creative endeavors can inform my programming career and how my programming career can inform my creative endeavors. I’d be lying if I said I wasn’t nervous about this whole career change, but it’s very exciting as well. I’m very grateful for all I’ve learned at Flatiron, and I can’t wait to see what’s next!