Managing Vacation Homes with Rails 
Tags: womenintech, flatironschool, rails, webdev
Published: 2020-12-03 18:14:50

![Vacation-Home](https://media.giphy.com/media/3ohzh4m3M4MH2WKdpe/giphy.gif) 

It's December 2020 and Los Angeles has just been issued our second 'Stay At Home' order. So when I was tasked with building a Rails-based web application for Flatiron School's third module project, I knew immediately that I wanted to create something that would allow me to fantasize about once again getting out of the house. After months of quarantining and dreaming about one day vacationing again, I decided to create a web application for users to be able to manage their vacation homes. 

The project had a number of specific requirements. The first of which was that I had to have at least two `has_many, through:` relationships. I decided to initially create three models for my project. I knew that I would have a user model and that each user would `has_many :properties` and `has_many :locations, through: :properties`. That in turn would make my `Location` model `has_many :properties` and `has_many :users, through: :properties`. These relationships made my `Property` model serve as my joins table, uniting my `User` and `Location` models. I knew my property would have user-submittable attributes for bedrooms and bathrooms, but what fun is a vacation property if it doesn't have amenities?! Enter my `Amenity` model. 

![Hot-tub](http://gph.is/2eQou0d)

Naturally, a vacation property `has_many :amenities` but an amenity also `has_many :properties`. I couldn't just have an `Amenity` model. I needed another joins table to connect my properties and amenities. My new `PropertyAmenity` model and respective data table would serve as a more standard joins table, just working to connect those two models.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/exfm5mzgvrvorfupauc7.png)

The other major requirement for this project was to have the capability to have 3rd authentication either through Github, Twitter, Facebook, or Google. I decided to include options for both Github and Google. Thanks to the smarts of my fellow classmate, CJ, I was able to use both platforms to authenticate users in my application. Once I had these first steps set up I started to add functionality to my site. 

My main form to create a new property needed to be set up with nested form capability so that a user could create a new location for a property as well as a new amenity if they have one that isn't already listed. To do this, I had to set up my Property model to accept nested attributes for both a location and an amenity. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sv8tfhwso4byxg5llqwe.png)

I included validations to ensure that the names for both a location and amenity could not be blank and then set up my `property_params` to permit the nested attributes for each. In addition to permitting these nested attributes, I also had to permit `amenities_ids:[]` if a user were to select amenities that had already been created and `location_id` if a user were to select a location that already exists. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7ikzeo6s05gbdph37dc5.png)

Once I had my basic CRUD functionality set up for a user's properties, I wanted to add the ability for someone to add images. I had no idea where to begin but was lucky enough to stumble upon a very helpful Medium article by Ana Harris that walks through a step-by-step guide to adding upload image functionality using Active Storage. I installed active record storage in my terminal and that immediately generate two tables in my database:
 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/syh22ggy869n9zmy84ow.png)

Once that was set up, I simply had to add `has_one_attached :avatar` to my Property model and set up my property_params to also permit :avatar (which is what I decided to call my image). I added a simple line of code to my view to be able to disply the image if it was uploaded: 

```<% if p.avatar.attached? %>
        <img src="<%= (url_for(p.avatar)) %>" class="card-img-top" alt="...">
        <% end %>```

Ta-da! Now a user can admire their gorgeous vacation properties in all their visual glory!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rhftxlze8lytrqjsrz9m.png)

Thanks for reading! You can watch a full run-through demo of my app here: https://www.youtube.com/watch?v=v6jWvsM1jN0