Phase-5 / Building an Online Store using Active Record Associations
Published: 2023-03-13 07:22:53

For my Phase 5 project, I decided to try building an online store --however, I definitely wanted this store to have a sense of community. I want users to have multiple roles. For example, as a single user, I wanted the ability to _sell_ my own items as a **seller** and _purchase_ items (sold by other users) as a **buyer**.

To do this, I would have to take advantage of [Active Record Roles](https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html).

## What are Active Record Roles?

Active Record roles are a way to define different roles or user types within an application and assign specific permissions or behaviors to those roles. In a multi-role application like the online store I was building, where users may have different abilities and access levels depending on their role, Active Record roles can be a powerful tool for managing and controlling user behavior.

For example, in my online sneaker store, I want to have two main user roles: `buyers` and `sellers`. **Buyers** will be able to view and purchase products.. 

![sneaker-app-buyer-view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5eo283x925uaw8jweah.png)

While **sellers** will be able to create and manage products, view total sales. 

![sneaker-app-seller-view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jx7o2q2ke7dvfr3911w.png)

### Why Roles are Better
D.R.Y. By using Active Record roles, you can easily assign these different permissions and behaviors to each role, without having to write complex authorization logic throughout your application.


## Setting Up My Database
Every great application has an even greater database behind it. So I started with setting up my database migration using Rails. I created this migration by adding foreign keys for the `seller_id` and `buyer_id` roles to my users table. 

```
rails generate migration CreateUserRoles seller:references buyer:references
```

These columns will be used to reference the User record for the seller or buyer associated with a given product listing or purchase through foreign keys.


## Setting Up My Models
In my User model, I defined the associations for the _seller_ and _buyer_ roles using the has_many method:

```
class User < ApplicationRecord
    has_secure_password
    
    has_many :listings, foreign_key: :seller_id
    has_many :purchases, foreign_key: :buyer_id
end
```


## Setting Up My Controller
Now that I've set up my roles and associations, I can use them to implement role-based functionality in my web store application. 

For example, if a user is a `seller`, they should be able to create and manage `listings` in the store:

> (_There's probably a better way to write this, but we can save that for another blog_)
```
def create
        seller = current_user
        sneaker = Sneaker.create(sneaker_params)
        listing = Listing.new(listing_params)
        listing.seller_id = seller.id
        listing.sneaker_id = sneaker.id
    
        if listing.save
          render json: listing, status: :created
        else
          render json: listing.errors, status: :unprocessable_entity
        end
    end
```

The same would go for `purchases`. I can set up my purchases controller to associate the `buyer_id` with the `current_user.id`.

Pretty cool! Although this was little confusing to grasp at first, it's still great to know about this feature! From here, I can continue building special feature in my application based on the user's role.