My First Full Stack Project-Elite Residency
Tags: beginners, ruby, sinatra, programming
Published: 2023-02-15 03:24:19

I'm wrapping up my first full stack project utilizing Sinatra framework. This project has proven to be extremely challenging and difficult, leaving me feeling unsure and struggling to find solutions at times. However, it helped me enhance my problem-solving abilities and allowed me to be the detective of my own puzzle. So here's a snippet of my project, highlighting Active Record in Ruby.

#### PROJECT IDEA

I developed a real estate application that enables potential buyers, sellers, and investors to search for information based on specific filters like location, price, square footage, number of bedrooms/bathrooms, etc. Additionally, users can manage listings by adding new properties, tracking availability, and deleting inactive listings. They can also adjust listing prices to reflect market value changes.

![video](https://j.gifs.com/jY98gz.gif)

**BASIC REQUIREMENTS**

![real estate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n69cse9iva5z6s6or6aa.png)

#### WHAT IS ACTIVE RECORD

> 
Active Record is an architectural pattern used in software engineering to provide an object-relational mapping (ORM) between database tables and the classes that represent them in an application. It is a design pattern commonly used in the development of database-backed web applications.

> 
For example, instead of writing raw SQL statements to perform database operations, you can use the Active Record library to perform these operations using the methods and properties of objects representing the data. This can lead to more maintainable code and can help reduce the risk of errors or security vulnerabilities in the application.

**Active Record Associations**

Association is a feature that enables us to define connections between different models. In my real estate app, I have established a one-to-many relationship between the "Listing" model and the "Subdivision" model. This relationship demonstrates that a single subdivision can have multiple listings, and each listing belongs to only one subdivision.


![class subdivision](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3326tjzmzypwkmwh92f.png)

![class listing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1hcxcs48a1xgs875w4dd.png)

Active Record Association makes it so much easier to work with your database, and keeps code more organized and maintainable.

This is how my Entity Relationship Diagram (ERD)look like:
![my table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6v9nm1ta68nl1nr9yjx1.png)



**Active Record Migrations**

Another feature that is useful in Ruby with Sinatra is Migrations.  It provides us a way to manage database schema and allows developers to define set of transformations like example creating tables, adding and removing columns, add details, modify index and more. 

In the world of coding, we are fortunate to have a useful tool in Ruby that can automate tasks and simplify our lives as developers. This tool is called Rake, and it performs tasks that we define for it. By executing tasks from the command line, we can use Rake to perform jobs such as running migrations using "rake db:migrate" and seeding our database with "rake db:seed".

***Creating Migrations Using a Rake Task***
I use this command line to create my table for my 2 models:

```
` $ bundle exec rake db:create_migration NAME=create_model_name`
```

![subdivision-table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0t72g1orce3j2zl43hv.png)

Note that : The id column is generated automatically for every table! So there is no need to specify it in the db/migrations file.

Thanks to the flexibility provided by rake tasks and migrations, I have been able to make modifications to my table at any time of day, even as I changed my mind quite a few times during the project build.

This is how I add another column in one of my models:

```
$ bundle exec rake db:create_migration NAME=add_active_to_listings
```

![add-column](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fcsmc2sb7mxa7tm7j2br.png)

To remove simply state remove instead of add:

```
$ bundle exec rake db:create_migration NAME=remove_status_to_listings
```

![remove column](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bquyo7zvhm1j1kde9m1j.png)
For full lists of methods click the link here:
[Active Record Migrations](https://guides.rubyonrails.org/active_record_migrations.html)

***Seeding Data***

In Ruby, you can seed data by using faker gem or creating a seed file that populates your database with built-in 'db/seeds.rb' file.  With Active Record you can create new records in your database like:

```
# db/seeds.rb
User.create(name: 'Jane Doe', email: 'jane.doe@example.com')

```
Then run the seed file by using this command:

```
 $ bundle exec rake db:seed
```
How I created my Subdivision model:

![seed-subdivision](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3d4xzkss6m774orrwyc3.png)

Now, what is the reason for adding...

`puts "🌱 Seeding spices..."

puts "Deleting old data..."

and why use Listing.destroy_all and Subdivision.destroy_all before seeding? This is to prevent duplicates and ensure that the database is empty before creating new records. If there are existing records that match the new records in some way, such as having the same primary key or unique constraint, then the new records will fail to save and an error will be raised. Therefore, it is good practice to use the destroy_all method.

***C R U D Operations***

CRUD Operations is a term used to describe the basic functionalities that an application must provide to its users to interact with the system's data. The acronym stands for Create, Read, Update, and Delete. In my real estate app, I made sure to include these four operations. Users can create new subdivisions and listings via a form, update the list price, and delete specific listings when they are no longer active. Additionally, users can read or retrieve information about a listing or subdivision.

You can define a route using the get, post, put, delete, or patch methods of the Sinatra::Base class. Showing you examples of how you can define a route in an application controller:

This code defines a route handler for a GET request to the /subdivisions path in a Sinatra application. When a user accesses this path using their browser or a client, the code will be executed and a response will be returned to the user.

![Get Req](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3q2xtksyb4vd0bjv09o6.png)


After fetching the Subdivision records, the code calls to_json on the resulting ActiveRecord relation. This method converts the ActiveRecord relation to a JSON string, which can be sent back as the response body to the user. The include: :listings option passed will result in a nested JSON object that contains the Subdivision records as well as their associated Listing records.

Using the create method on the Subdivision model. 
![post req](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ptcyts732z6ne6fo70n6.png)

The attributes of the new record are set based on the values of the image_url, name, and overview parameters in the request. These parameters are obtained using the params hash, which is automatically populated by Sinatra based on the contents of the request body.

I have implemented the functionality for updating and deleting Listing records here:


![Patch/Delete](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0guwetsvf77avtavzi5n.png)

Both of these methods utilize HTTP methods to perform specific actions on the Listing records. The PATCH method is used for updating, while the DELETE method is used for deleting. These methods are commonly used in RESTful API design and allow for a clear and consistent interface for interacting with resources in a web application.