<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nicholas Mendez</title>
    <description>The latest articles on Forem by Nicholas Mendez (@nickmendez).</description>
    <link>https://forem.com/nickmendez</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F794391%2F4d1e6a96-8f1d-4585-a6e4-fd4bcb3c47b0.jpg</url>
      <title>Forem: Nicholas Mendez</title>
      <link>https://forem.com/nickmendez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nickmendez"/>
    <language>en</language>
    <item>
      <title>How to Configure Active Storage with Amazon AWS S3 Cloud Storage</title>
      <dc:creator>Nicholas Mendez</dc:creator>
      <pubDate>Wed, 28 Sep 2022 19:58:25 +0000</pubDate>
      <link>https://forem.com/nickmendez/how-to-configure-active-storage-with-amazon-aws-s3-cloud-storage-h</link>
      <guid>https://forem.com/nickmendez/how-to-configure-active-storage-with-amazon-aws-s3-cloud-storage-h</guid>
      <description>&lt;h2&gt;
  
  
  Active Storage Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Active Storage is a ruby gem that facilitates uploading files to a cloud storage service and attaching those files to Active Record objects.&lt;/strong&gt; Testing and development environments have a local disc service option for storing files locally. Active Storage utilizes naming conventions similar to Active Record , making it very intuitive and easy to integrate into any Ruby on Rails application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;

&lt;p&gt;Please feel free to visit my gitHub repository or my website to see the the results of this tutorial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://extrackt.onrender.com/" rel="noopener noreferrer"&gt;https://extrackt.onrender.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repository: &lt;a href="https://github.com/nickmendezFlatiron/extrackt" rel="noopener noreferrer"&gt;https://github.com/nickmendezFlatiron/extrackt&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If you already have Active Record installed , navigate down to the "Configuring Active Storage for S3" section.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Setup Active Storage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I highly recommend planning out your application prior to installing Active Storage.&lt;/strong&gt; Map out your models, attributes, associations, and routing logic. I recommend using an entity relationship diagram (ERD) to map out your model/table relationships &lt;a href="https://dbdiagram.io/home" rel="noopener noreferrer"&gt;dbdiagram&lt;/a&gt;. Build out a frontend that can capture files for you to test and troubleshoot Active Storage.&lt;/p&gt;

&lt;p&gt;1) Install the Active Storage gem from your terminal , or add the Active Storage gem to your Gemfile and run bundle install&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

gem 'activestorage', '~&amp;gt; 7.0', '&amp;gt;= 7.0.4'


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;2) As an option , install Active Storage Validator to add validations to your Active Storage uploads&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

gem 'activestorage-validator', '~&amp;gt; 0.2.2'


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;3) Migrate the Active Storage auto generated tables to your database&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

rails db:migrate


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;4) Create and migrate the rest of your Models , preferably using a scaffold or resource generator. When using generators , Active Storage attachments follow the convention below. Use the attachments (plural) to setup a one-to-many relationship between records and files&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

rails g resource User avatar:attachment photgraphs:attachments


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;At this point , your app_name/app/db/migrate folder should look similar to this&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj15hrpol8a88wx3jd48g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj15hrpol8a88wx3jd48g.png" alt="Active Storage Migrations"&gt;&lt;/a&gt;&lt;br&gt;
4b) Alternatively, open your model and define the attachment directly in the model. Setup a one-to-many relationship between records and files using the has_many_attached naming convention&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

class User &amp;lt; ApplicationRecord
  has_one_attached :avatar
  has_many_attached :photographs 
end


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Configuring Active Storage for S3
&lt;/h3&gt;

&lt;p&gt;1) Add the AWS S3 Gem to your Gemfile and run bundle install&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

gem "aws-sdk-s3", require: false


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;2) Set your Active Storage service in config/environments folder&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to use S3 service in your development and production environment , include the following code in your config/environments/development.rb and config/environments/production.rb files.
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Store files on Amazon S3.
&lt;/h1&gt;

&lt;p&gt;config.active_storage.service = :amazon&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- if you'd like to store files locally in your development environment, copy/paste the following code in your config/environments/development.rb file.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;config.active_storage.service = :local&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3) Inside your config folder , create a storage.yml file if one does not exist. 
![storage.yml file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0i6ei8q5la2et9e7p41b.png)
- Inside the config/storage.yml file , copy/paste the following code. We will enter a bucket and region in a later step

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;local:&lt;br&gt;
  service: Disk&lt;br&gt;
  root: &amp;lt;%= Rails.root.join("storage") %&amp;gt;&lt;/p&gt;

&lt;p&gt;test:&lt;br&gt;
  service: Disk&lt;br&gt;
  root: &amp;lt;%= Rails.root.join("tmp/storage") %&amp;gt;&lt;/p&gt;

&lt;p&gt;amazon:&lt;br&gt;
  service: S3&lt;br&gt;
  access_key_id: &amp;lt;%= Rails.application.credentials.dig(:aws, :access_key_id) %&amp;gt;&lt;br&gt;
  secret_access_key: &amp;lt;%= Rails.application.credentials.dig(:aws, :secret_access_key) %&amp;gt;&lt;br&gt;
  bucket: "bucket_name_here"&lt;br&gt;
  region: "your_region_here"&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4) Login to your AWS account or [create a free account.](https://aws.amazon.com/s3/pricing/?loc=ft#AWS_Free_Tier)

5) Under the services tab, navigate to the S3 
![Amazon S3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqtgcodiapftc02fekku.png)

6) Create a New Bucket by clicking the orange Create Bucket button
![create bucket](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vig3r9z3czityo21y80p.png)
7) Under General Configuration:
- use your application's name as the bucket name.
- Select the region which is closest to your location.
![general config](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qvgjougv40injn0n7l9x.png)
8) Leave default settings for the rest of the bucket and click the create bucket button on the bottom of the page.

9) Inside the config/storage.yml file from step 3 , enter the bucket name and region from the bucket you created.
![myrails app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sd2dc1329yfr3ftniyu3.png)
![VS code rails app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xg5cr896dne1jfi8v3v0.png)

10) Navigate back to your AWS website tab and select IAM under the services tab. Click on Users and then click on the blue Add Users button
![AWS IAM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xxedwocyp3n73e4aq5hl.png)
![AWS Users](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/px6ui3f7t2iy3ppd5b36.png)
![Add users](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8oa1l7gjoj2ljvdxelh7.png)

11) Use your application's name as the user name and select programmatic access.
- Select Attach Existing Policies tab and search for S3. 
- Select the Amazon S3 Full Access policy.

![step 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqw7nih0oo2p909vmi2g.png)
![S3 Access](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fo32mvy33cqhcgkdu9i3.png)

![User](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzxlmd8xssyih4dir4j3.png)
12) Navigate back to your IDE and open a terminal. cd into your root directory folder and run the following command.
- We will be adding our AWS S3 user information into an encrypted file because we do not want to store sensitive information in plain text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;EDITOR=VIM bundle exec rails credentials:edit&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Note: If you encounter an "Couldn't decrypt config/credentials.yml.enc. Perhaps you passed the wrong key?" error , delete the config/credentials.yml.enc file and rerun the command.

13) Inside the VIM editor , press the i key to edit the contents inside the terminal window. 
- copy/paste the secret access key and access_key_id from the S3 user you created.
- make sure to uncomment 
![VIM Editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sy8fh8y4h3zjrku000q8.png)

14) Press the escape key and then type :qa to exit and save the file

At this point , everything is set up. If you plan on deploying your project , make sure to commit and push to your Github Repo. Once you have a URL for your live application , configure CORS in your S3 bucket under the Permissions tab. Here is a CORS configuration example

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[&lt;br&gt;
    {&lt;br&gt;
        "AllowedHeaders": [&lt;br&gt;
            "*"&lt;br&gt;
        ],&lt;br&gt;
        "AllowedMethods": [&lt;br&gt;
            "GET",&lt;br&gt;
            "POST",&lt;br&gt;
            "PUT"&lt;br&gt;
        ],&lt;br&gt;
        "AllowedOrigins": [&lt;br&gt;
            "&lt;a href="https://www.example.com" rel="noopener noreferrer"&gt;https://www.example.com&lt;/a&gt;"&lt;br&gt;
        ],&lt;br&gt;
        "ExposeHeaders": []&lt;br&gt;
    }&lt;br&gt;
]&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
---
Resources
- [Active Storage Guide](https://edgeguides.rubyonrails.org/active_storage_overview.html#attaching-files-to-records)
- [Amazon AWS](https://aws.amazon.com/s3/)
- [AWS CORS Configuration](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ManageCorsUsing.html)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>rails</category>
      <category>tutorial</category>
      <category>aws</category>
      <category>react</category>
    </item>
    <item>
      <title>Heroku Alternative: How to Deploy A ReactJS Rails API App to Render</title>
      <dc:creator>Nicholas Mendez</dc:creator>
      <pubDate>Wed, 28 Sep 2022 01:06:15 +0000</pubDate>
      <link>https://forem.com/nickmendez/heroku-alternative-how-to-deploy-a-reactjs-rails-api-app-to-render-2k17</link>
      <guid>https://forem.com/nickmendez/heroku-alternative-how-to-deploy-a-reactjs-rails-api-app-to-render-2k17</guid>
      <description>&lt;h2&gt;
  
  
  The Fall of Heroku
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Heroku recently announced they are discontinuing some of their free plan options starting November 28.&lt;/strong&gt; Free plans widely popularized Heroku as a go-to platform as a service (PaaS) for developers to deploy their applications and APIs. Consequently, many hobbyists, programming courses, and existing Heroku projects are looking to migrate to a comparable alternative. After spending time weighing out the available options , I decided to deploy my future projects to Render.com .&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose Render.com?
&lt;/h2&gt;

&lt;p&gt;Render.com provides free plans for deploying static sites , web services with HTTP/2 and full TLS, PostgreSQL databases, and Redis integration. The deployment process is beginner-friendly and the documentation is easy to follow. Upgrading to a starter plan costs less than a monthly Spotify account. &lt;strong&gt;Setup an AWS S3 bucket for file storage, and you have yourself a great starting point for any application at no cost.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're starting from a ground zero, follow these instructions to setup your environment to ensure the deployment goes smoothly. If not , skip down to "Configuring Your App for Render"&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create A React Rails API App from scratch
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;create a Rails API in a new project folder&lt;br&gt;
&lt;code&gt;rails new app-name --api --minimal --database=postgresql&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cd into the folder and run the following command in terminal&lt;br&gt;
&lt;code&gt;bundle lock --add-platform x86_64-linux --add-platform ruby&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build out an MVP with routes , controllers, models , migrations, and create a database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create a new React application in a client folder inside the root directory&lt;br&gt;
&lt;code&gt;npx create-react-app client --use-npm&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a request proxy inside the client/package.json file&lt;br&gt;
&lt;code&gt;"proxy": "http://localhost:3000"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the start script in client/package.json file &lt;br&gt;
&lt;code&gt;"scripts": {&lt;br&gt;
"start": "PORT=4000 react-scripts start"&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point , your file structure should resemble something like this, minus a few optional folders and config files, which we will soon add.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qjnv1nclxy33wud825w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qjnv1nclxy33wud825w.png" alt="file-structure"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Configuring Your App for Render
&lt;/h2&gt;

&lt;p&gt;Now you're ready to configure your app to deploy it to Render.&lt;br&gt;
Follow the following steps to configure your application for deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Sign up for &lt;a href="https://render.com/" rel="noopener noreferrer"&gt;Render.com&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) Open config/database.yml file and find the production section.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modify it to gather the database configuration from the DATABASE_URL environment variable. &lt;/li&gt;
&lt;li&gt;This should be located at the bottom of the file.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;production:
  &amp;lt;&amp;lt;: *default
  url: &amp;lt;%= ENV['DATABASE_URL'] %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;3) Open config/puma.rb and make sure the following lines are uncommented.&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feel free to clear out the file and copy/paste the code block below.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

port        ENV.fetch("PORT") { 3000 }

environment ENV.fetch("RAILS_ENV") { "development" }

pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
workers ENV.fetch("WEB_CONCURRENCY") { 4 }
preload_app!
plugin :tmp_restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;4) Open config/environments/production.rb and  enable the public file server when the RENDER environment variable is present.&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is an existing line of code in the file , which we are modifying.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? || ENV['RENDER'].present?

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;5) Create a build script to build out your app when you deploy it.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This script will automate the build process and update your application every time it is deployed.&lt;/li&gt;
&lt;li&gt;inside your app-name/bin folder , create a file called render-build.sh&lt;/li&gt;
&lt;li&gt;copy/paste the following code into the render-build.sh file
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env bash
# exit on error
set -o errexit

bundle install
# clean
rm -rf public
# build
npm install --prefix client &amp;amp;&amp;amp; npm run build --prefix client
# migrate
bundle exec rake db:migrate
# postbuild
cp -a client/build/. public/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;your file should look like this when you're done
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftyknodd2z8b73cds6u74.png" alt="build script"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6) Make sure the script executes by running the following command in terminal.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;chmod a+x bin/render-build.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7) Commit and push these changes to your GitHub Repository&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Deploying To Render
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;8) Inside the root directory , create a file name render.yaml. Copy/paste the following code into the file. Replace app_name with your application's name&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;databases:
  - name: app_name
    databaseName: app_name
    user: app_name

services:
  - type: web
    name: app_name
    env: ruby
    buildCommand: "./bin/render-build.sh"
    startCommand: "bundle exec puma -C config/puma.rb"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: app_name
          property: connectionString
      - key: RAILS_MASTER_KEY
        sync: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file should look like this when you're done.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwnx1jzn1mk8p8w0hx4m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwnx1jzn1mk8p8w0hx4m.png" alt="render yaml file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9) Commit and push these changes to your GitHub Repository&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10) Navigate to the Render website and make sure you're logged in.&lt;/strong&gt; On the Render Dashboard, go to the &lt;a href="https://dashboard.render.com/blueprints" rel="noopener noreferrer"&gt;Blueprint&lt;/a&gt; page and click the New Blueprint Instance button. Select your repository (after giving Render the permission to access it, if you haven’t already).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11) Your repository branch should already be set to "main", or select whichever branch you want to deploy. I used my "main" branch.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12) In the deploy window, set the value of the RAILS_MASTER_KEY to the contents of your config/master.key file.&lt;/strong&gt; Then click Approve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;13) Navigate to your Dashboard and click on the web service you just created.&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24j5xao3r8ei6pad3t1f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24j5xao3r8ei6pad3t1f.png" alt="web service"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;14) Click on the blue Manually Deploy button on the top right hand side and select "clear build cache and deploy"&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sxeluamjlu4evkprzkv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sxeluamjlu4evkprzkv.png" alt="deploy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;15) Wait for your app to successfully deploy and click on the generated URL &lt;em&gt;your_app_name.onrender.com&lt;/em&gt; at the top.&lt;/p&gt;

&lt;p&gt;And that's how you deploy a full-stack React/Rails API application to Render. If you have any questions , feel free to drop a comment below. If you're a Flatiron Student, drop a comment below if this has helped you.&lt;/p&gt;

&lt;p&gt;To see the final result, visit my gitHub repository and Render website if you'd like.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://extrackt.onrender.com/" rel="noopener noreferrer"&gt;https://extrackt.onrender.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repository: &lt;a href="https://github.com/nickmendezFlatiron/extrackt" rel="noopener noreferrer"&gt;https://github.com/nickmendezFlatiron/extrackt&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Resources
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://render.com/docs/deploy-rails#create-a-build-script" rel="noopener noreferrer"&gt;Getting Started with Ruby on Rails on Render&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>rails</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The Pitfalls of the Destroy Method in Active Record</title>
      <dc:creator>Nicholas Mendez</dc:creator>
      <pubDate>Thu, 25 Aug 2022 21:13:11 +0000</pubDate>
      <link>https://forem.com/nickmendez/phase-4-project-blog-fb5</link>
      <guid>https://forem.com/nickmendez/phase-4-project-blog-fb5</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;The Slippery Slope Of Associations&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Association Principle is when we mentally connect things together , and then automatically follow the links we have created.&lt;/strong&gt; We create associations to simplify our decision making process. And sometimes , the associations we create are wrong. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's a scenario&lt;/strong&gt;. You go to the store to buy refreshing bottle of cold-pressed juice. You find one in the fridge and proceed to read the ingredients. Then, you see another flavor on the shelf and decide to buy that instead. By the time you get in your car , you notice the juice you bought is made from concentrate. Tsk tsk , you didn't read the ingredients the second time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Well , what happened?&lt;/strong&gt; You mentally associated the second juice with cold-pressed juices. Why? Because it was positioned next to the original bottle you picked up. Thus , you did not read the label and ended up with an undesirable outcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning occurs through the failures which we experience , not our successes.&lt;/strong&gt; And similarly to the juice fiasco , I learned the pitfalls of the association principle while using Active Record's destroy method.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Active Record?
&lt;/h2&gt;

&lt;p&gt;Active Record is a very powerful ORM in the Ruby on Rails library. It uses the convention over configuration paradigm to facilitate DRY code ,allowing the developer to focus on higher order tasks. Some of the most powerful macros within Active Record are Associations. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Associations are a set of macro-like class methods for tying objects together through foreign keys&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Associations unlock a multitude of class methods, which make it easier to interact with and manipulate associated records through the relationships established between data tables. One of these methods being the destroy method. Let's explore the intricacies of the destroy method through a few examples I pulled from my most recent project , Flood Mail. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Flood Mail&lt;/strong&gt; is a messaging platform built around game theory principles. Each user has complete control over their data. Delete a message , and it is deleted for both users. If a user deletes their account , then all associated data is deleted too.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Table Associations
&lt;/h3&gt;

&lt;p&gt;If you're not familiar with table associations ,&lt;a href="https://dev.toIf%20you're%20not%20familiar%20with"&gt;check out this page here&lt;/a&gt;. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3gyv7y0kgi9z6go2vr9c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3gyv7y0kgi9z6go2vr9c.png" alt="Table Relationships"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Calling Destroy on an Object
&lt;/h2&gt;

&lt;p&gt;According to the Ruby docs , the destroy method "Deletes the record in the database". Simple enough. We call it on an instance and ActiveRecord removes it from the database.&lt;/p&gt;

&lt;p&gt;For the sake of this example , let's assume the Email Threads table is not referenced in any other table. The destroy method will function as follows. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2c6xspcao8n1qinaqc9r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2c6xspcao8n1qinaqc9r.jpg" alt="Rails Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now , in the context of Flood Mail's backend, Email Threads are referenced in 2 other tables : Messages , and User Email Threads. Unless we setup the proper associations , the destroy method will throw an error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tx9sdzhr6t3orolih49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tx9sdzhr6t3orolih49.png" alt="Dependent Error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example , Rails is attempting to save us from ourselves. If we remove the object in the example above , then we will have orphaned records in the dependent database tables. &lt;/p&gt;
&lt;h3&gt;
  
  
  Using Destroy Method with Associations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;To remedy this , we use dependent: :destroy option inside our Email Thread model&lt;/strong&gt;. Now , whenever we destroy an Email Thread , the destroy method will be called on all associated records as well. The result of calling the destroy method is slightly different now , but it's easy enough to remember. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pczchm9eiax28rm3vo0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pczchm9eiax28rm3vo0.png" alt="dependent destroy"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Using Destroy Method with Join Tables
&lt;/h3&gt;

&lt;p&gt;This example builds on the previous. We assume we have all the proper associations setup in our Models; therefore, we shouldn't receive any errors or orphaned messages. &lt;strong&gt;We want to destroy all the associated messages for our selected email thread. Since this is a collection of messages, we use the destroy_all syntax.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Destroy and destroy_all will always call the destroy method of the record(s) being removed so that callbacks are run.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqe98rns2jfsf14fwvyc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqe98rns2jfsf14fwvyc.png" alt="destroy all method on a collection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our destroy method has now removed every record in our collection of messages. If we try to find one of the deleted records ,we should expect an error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6dqx2z8i16ntp2yyjvj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6dqx2z8i16ntp2yyjvj.png" alt="Record not found error"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Using the Destroy Method on Join Tables PT.2
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Let's apply the same logic from our previous example to a user object.&lt;/strong&gt; We'll assign the first user the variable user , and we'll delete the user's collection of email threads. Exactly as we did with the messages collection in for email thread. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fff29fpcge9ue47ugilgx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fff29fpcge9ue47ugilgx.png" alt="destroy all join table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And now if we try to find one of the deleted email threads , we should expect an error. Right?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnblopjx2s1zpdibpf1wb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnblopjx2s1zpdibpf1wb.png" alt="Found the record we shouldn't have found"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The "Gotcha" Moment
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Yet again we've been bamboozled by the association principle.&lt;/strong&gt; Why are we able to find the record , it should have been destroyed? Well , let's dive into the Ruby on Rails docs to find out what actually gets deleted when we use these methods.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftbb88obnk4twh5yoolai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftbb88obnk4twh5yoolai.png" alt="ruby docs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As it turns out , the join records are being deleted. If we want to delete the associated records themselves ,we will need to iterate over our collection and call the destroy method on each object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user.email_threads.each {|e| e.destroy}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;In Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;By now , we've learned to should measure twice and cut once. By understanding what the destroy method is doing in different use cases , we'll avoid the possibility of creating orphaned records and corrupting our database tables. We've learned how to setup the proper associations to delete records and their dependents , as well as any other associated records using Active Record methods. &lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/nickmendezFlatiron/flood-mail" rel="noopener noreferrer"&gt;Flood Mail Repository&lt;/a&gt;&lt;br&gt;
&lt;a href="https://guides.rubyonrails.org/association_basics.html#creating-join-tables-for-has-and-belongs-to-many-associations" rel="noopener noreferrer"&gt;Active Record Associations&lt;/a&gt;&lt;br&gt;
&lt;a href="https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many" rel="noopener noreferrer"&gt;Ruby on Rails Active Record Documentation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>tutorial</category>
      <category>oop</category>
    </item>
    <item>
      <title>ActiveRecord Methods to keep Your Databases Clean</title>
      <dc:creator>Nicholas Mendez</dc:creator>
      <pubDate>Wed, 27 Jul 2022 02:46:00 +0000</pubDate>
      <link>https://forem.com/nickmendez/activerecord-methods-to-keep-your-databases-clean-14e4</link>
      <guid>https://forem.com/nickmendez/activerecord-methods-to-keep-your-databases-clean-14e4</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Contaminated databases are a drag on performance.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In machine learning , datasets contaminated with duplicates cause models to learn artificial patterns that do not exist. In the real-life context of emergency dispatch call centers, multiple calls about the same complaint cause multiple officers to respond to the same incident. &lt;br&gt;
Consequently , misallocated resources resulting from poor dataset structure create larger problems than originally encountered. &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The solution is naïvely simple : Don't enter conflicting records in our dataset.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;While the constraints and parameters of every dataset will vary , the general process and application of said solution is the same.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify which parameters will be used to find existing records in your model's dataset. &lt;/li&gt;
&lt;li&gt;Uniquely identify each entry when submitting an entry/record.&lt;/li&gt;
&lt;li&gt;Handle all responses from querying the dataset.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Simple enough , right? Fortunately, ActiveRecord offers a few finder methods. These methods allow us to determine whether or not a conflicting record exists prior to entering a new record into our database. &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Let's explore how to maintain a stable and clean database through  practical examples.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Queue Wag n' Walk , a schedule planner tailored to dog walking. There are a few different headaches that will come from contaminating the database ; let's identify the different entries that may compromise our table of appointments. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkigzbbpwdczqbdmyxxnd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkigzbbpwdczqbdmyxxnd.png" alt="Wag and Walk Dog Walker Schedule Planner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This example requires a basic understanding of ActiveRecord gem , table associations , and SQL tables.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1. Identify Useful Parameters&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Each scheduled appointment has 4 different user inputs ; a date/time , a dog , a walker (employee) , and the walk duration. A few potential scheduling conflicts should stand out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scheduling a walker for a time slot that conflicts with their current appointments&lt;/li&gt;
&lt;li&gt;Scheduling a dog for a time slot that conflicts with their current appointments&lt;/li&gt;
&lt;li&gt;Scheduling the same appointment twice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyhxjvs628axzczs7yoz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyhxjvs628axzczs7yoz.png" alt="Calendar and Appointment Form"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first method to consider is the find_or_create_by method.&lt;/strong&gt;&lt;br&gt;
This method either finds the first record with the provided attributes, or creates a new record if one is not found. This method used on its own is useful when we're searching for an exact record , or when our dataset is simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Appointment.find_or_create_by({ 
employee_id: params[:employee_id] , 
start: params[:start]})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no record with the provided employee id and starting appointment date/time is found in our Appointments Table, then a new record is entered. &lt;/p&gt;

&lt;p&gt;If we attempt schedule an appointment while an existing appointment is in progress , our find_or_create_by method will not notice and will enter a conflicting appointment for our walker into our schedule. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Method Chaining&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The second method to consider is actually a combination of multiple methods, known as method chaining. By method chaining , we are able to apply multiple conditions to vet and find records in our database. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.where Method&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exist = Appointment.where({
      start: params[:start] , 
      dog_id: params[:dog_id]
      })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.where selects all records that match the attributes passed to the method. In this case , exist will equal all appointments with the start time matching the provided start time , and the dog id matching the dog id. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.or Method&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; exist = Appointment.where({
      start: params[:start] , 
      dog_id: params[:dog_id]
      }).or(Appointment.where({start: params[:start] , 
            employee_id: params[:employee_id]}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chain the .or method to add a second condition to your query. In this case , we are looking for any appointment matching the provided start time and dog id , or any appointment matching the provided start time and employee id. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.find_all Method&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appt_in_progress_dogs = Appointment.all
.find_all {|a| a[:dog_id] == params[:dog_id]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The find_all method returns an array containing the records selected for which the given block returns a true value. In this case , we are finding all records from the Appointments table whose dog id matches the provided dog id.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.between? Method&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appt_in_progress_dogs = Appointment.all
.find_all {|a| a[:dog_id] == params[:dog_id]}
.find_all {|a| params[:start].between?(a[:start] , a[:end])}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The between method returns a true or false value. It determines whether or not a value is between a provided minimum or maximum. In this case , we want to find all records with a dog id matching the provided dog id. Then , out of those records , we want to find all cases where the new appointment starts while an existing appointment for the provided dog is in progress.&lt;br&gt;
 In other words , we do not want to schedule a walk for a dog if the dog is in the middle of a walk. The same case applies for any walker (employee).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.find_in_batches Method&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Appointment.find_in_batches(batch_size: 1000) do |a|
       a.find_by({start: params[:start]}) 
      end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The find_in_batches method is useful when working with large datasets. Provided the size of a batch , this method will only query the provided batch size at a time. This method will cut some of the performance issues that occur from working with larger datasets. &lt;/p&gt;

&lt;p&gt;We are able to be more intentional and specific about the types of records we want to find through method chaining.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Uniquely Identify Records&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This answer is fairly simple with Active Record. By using &lt;a href="https://edgeguides.rubyonrails.org/active_record_basics.html#migrations" rel="noopener noreferrer"&gt;Active Record Migrations&lt;/a&gt; , a primary key column is automatically generated , and each record entered to our table is assigned a unique id.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Handling Query Responses&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that we've queried the appointments table , we will conditionally respond to the user's new appointment request. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjadpj5xl5cb073n88efg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjadpj5xl5cb073n88efg.png" alt="Wag N Walk Backend Post Request Response"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IF Statement&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if !exist.exists? &amp;amp;&amp;amp;[*appt_in_progress_dogs,*appt_in_progress_walkers].length &amp;lt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The IF statement in our POST method makes use of the queries we executed.&lt;/strong&gt; If the new appointment request does not match any existing record exactly , then it passes the first condition in the IF statement. &lt;a href="https://andreigridnev.com/blog/2016-04-17-empty-blank-any-exists-methods-of-ruby-on-rails-activerecord/" rel="noopener noreferrer"&gt;The .exists? method&lt;/a&gt; returns true or false. In this case , if no record exists , then we proceed to test the second condition. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The second condition of the IF statement utilizes the splat (*) operator&lt;/strong&gt;, which functions similarly to Javascript (ES6) spread (...) operator. If no appointments in progress are found for the provided dog or walker, then the length of our array will be zero. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If both conditions are met , then a new Appointment will be created with the provided attributes sent by our front end and our response will be sent as a JSON object.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Else Statement&lt;/strong&gt;&lt;br&gt;
If either of the conditions return false , then our backend will send an error message response as a JSON object. Some errors may be more complex than others , and therefore , you may setup multiple conditions for multiple errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   fetch(`http://localhost:3005/appointments` , {
      method : 'POST' ,
      headers: { "Content-Type" : 'application/json'} ,
      body : JSON.stringify(newAppointment)
    })
      .then(r =&amp;gt; r.json())
      .then((appointment) =&amp;gt; {
        if(Object.keys(appointment).length === 1) {
          alert(appointment.error)
        } else {
          setAppointments([...appointments , appointment])
          alert(`Appointment for ${newDate} at ${time} has been scheduled`)
        }
      })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given the response received from our initial POST request , we alert the user of either a successfully scheduled appointment or with an error we sent from out backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The same queries and conditions may also be applied to PATCH request.&lt;/strong&gt; We also need to validate whether updating an existing appointment will cause the same contamination as our POST request. &lt;/p&gt;

&lt;h3&gt;
  
  
  In Conclusion
&lt;/h3&gt;

&lt;p&gt;ActiveRecord provides many useful methods for querying our databases. Chaining methods allow us to be more intentional and specific with our queries. Determine whether or not a conflicting record exists in our database , and conditionally respond to the possible outcomes.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Resources
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://towardsdatascience.com/how-to-deal-with-duplicate-entries-using-sql-4b017465d6dc" rel="noopener noreferrer"&gt;How to Deal With Duplicate Entries&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.sciencedirect.com/topics/computer-science/duplicate-record" rel="noopener noreferrer"&gt;CS: Duplicate Records&lt;/a&gt;&lt;br&gt;
&lt;a href="https://deepchecks.com/what-is-data-cleaning/" rel="noopener noreferrer"&gt;What is Data Cleaning&lt;/a&gt;&lt;br&gt;
&lt;a href="https://api.rubyonrails.org/classes/ActiveRecord/Batches.html" rel="noopener noreferrer"&gt;Ruby on Rails Docs&lt;/a&gt;&lt;br&gt;
&lt;a href="https://edgeguides.rubyonrails.org/active_record_basics.html#migrations" rel="noopener noreferrer"&gt;Active Record Migrations Docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>database</category>
      <category>beginners</category>
      <category>rails</category>
    </item>
    <item>
      <title>How to Setup Dynamic Routing in React to Improve UX</title>
      <dc:creator>Nicholas Mendez</dc:creator>
      <pubDate>Thu, 05 May 2022 23:45:19 +0000</pubDate>
      <link>https://forem.com/nickmendez/how-to-use-dynamic-routing-in-react-to-improve-ux-4i5e</link>
      <guid>https://forem.com/nickmendez/how-to-use-dynamic-routing-in-react-to-improve-ux-4i5e</guid>
      <description>&lt;p&gt;&lt;u&gt;Learn:&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why consistency within your app improves user experience&lt;/li&gt;
&lt;li&gt;How to utilize structure to create consistency&lt;/li&gt;
&lt;li&gt;How to implement dynamic Routing with React Router to make your app predictable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Two C's: Consistency and Comfortability&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;We have all heard the proverbial statement "If you build it , they will come".&lt;/strong&gt; By strategy and research we determine why "they" , or the target user,  "will come". We then build out an application to satisfy the "why", no matter how meaningful or trivial it may be.  &lt;strong&gt;Now I propose a new quote , "If they come , how long will they stay ?".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I bet you've shopped on Amazon before. No matter what product you want to fund, you use the same procedure. Enter a search keyword, sort the products, read a couple of reviews, add to cart , and checkout. Easy enough.&lt;/p&gt;

&lt;p&gt;It's this level of consistency that reinforces a positive user experience. If we deliver a consistent experience , then the user will have consistent expectations. Our decisions are easier to make when we know what to expect. Consequently , our user will become very comfortable with using our app. &lt;strong&gt;How the user interacts and responds to your app is what defines the user experience.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Achieve Consistency with React
&lt;/h3&gt;

&lt;p&gt;Much like Amazon , we want our users to stay. To show how to implement these principles , I built Order Pro. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd11mb38q830qekb951ha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd11mb38q830qekb951ha.png" alt="Order Pro"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Order Pro is an order management app tailored to small retail businesses. It allows users to create orders and record customer information. All of the orders are stored in a local database, which the user can access through a table of orders. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Major Key🔑  Alert: Structure your database before diving into the IDE. Know how you're going to store data before capturing and displaying it. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First , we need to capture the order information. We already know what information we need to capture because we've structured our database. And we capture this information with a controlled form. If you're not sure on how to setup a controlled form in React , I recommend this post on &lt;a href="https://medium.com/swlh/building-controlled-forms-using-functional-components-in-react-965d033a89bd" rel="noopener noreferrer"&gt;how to build a controlled form&lt;/a&gt; using React. We push every new order to a local JSON server file "db.json" as an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "orders": [
    {
      "name": "Johnny Appleseed",
      "email": "johnE@email.com",
      "date": "2022-04-01",
      "number": 1003,
      "items": [
        "3 shirts",
        "2 tables",
        "1 bag of soil"
      ],
      "fulfilled": false,
      "id": 1
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nqrwfpsqaqujnrrn4y0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nqrwfpsqaqujnrrn4y0.png" alt="Dashboard for all Orders"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Static Routes vs Dynamic Routes
&lt;/h2&gt;

&lt;p&gt;We've stored the array of order objects in State. Using React Components, we've created re-usable blocks of code to uniformly display each order. Every order is displayed as its own table row. We've even created a nice search bar feature to help our storeowner find an order. &lt;/p&gt;

&lt;p&gt;Up until this point , we've used &lt;a href="https://www.w3schools.com/react/react_router.asp" rel="noopener noreferrer"&gt;static routes&lt;/a&gt; to render our page components. Our Order Form , Order Dashboard , and Homepage are all paths we had to manually route. We want every order to have its own URL , where the storeowner can view the information we couldn't fit in the dashboard. &lt;br&gt;
Just as the table rows are automatically rendered, we also want our order pages to automatically route and respond to the order information we pass. We only need to create one component , OrderNumberPage , for all of the orders. Why? Because creating a static route for every order is as productive as catching wind in a jar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Fragment&amp;gt;
  &amp;lt;Navigation logo={logo}/&amp;gt;
  &amp;lt;Switch&amp;gt;
    &amp;lt;Route exact path="/orders"&amp;gt;
      &amp;lt;Orders&amp;gt;
        &amp;lt;SearchBar orders={orders} setSearch={setSearch} setFilter={setFilter} search={search}/&amp;gt;  
        &amp;lt;OrderTable orders={orders} setOrders={setOrders} url={url} search={search} filter={filter}/&amp;gt;
      &amp;lt;/Orders&amp;gt;
    &amp;lt;/Route&amp;gt;
    &amp;lt;Route exact path="/create-order"&amp;gt;
      &amp;lt;OrderForm orders={orders} setOrders={setOrders} url={url}/&amp;gt;
    &amp;lt;/Route&amp;gt;
    &amp;lt;Route exact path="/"&amp;gt;
      &amp;lt;HomePage logo={logo}/&amp;gt;
    &amp;lt;/Route&amp;gt;
    &amp;lt;Route exact path="/orders/:orderNumber" &amp;gt;
      &amp;lt;OrderNumberPage orders={orders}/&amp;gt;
    &amp;lt;/Route&amp;gt;
  &amp;lt;/Switch&amp;gt;
&amp;lt;/Fragment&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now that you've put your jar down , let's import our OrderNumberPage component to our App.js file and append it to our Switch Component(shown above).&lt;/strong&gt;&lt;br&gt;
I've decided to route the Order Number Page component next to the other static pages because I only want to render the details for the selected order. &lt;br&gt;
Taking a closer look at the URL for OrderNumberPage component , you'll notice the unique identifier &lt;strong&gt;:orderNumber&lt;/strong&gt;. This value will indicate the selected order to render. Later on , we will use the useParams Hook to access our orderNumber identifier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating Dynamic Links
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqq6b0fig397epu48bwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqq6b0fig397epu48bwe.png" alt="TableRow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look under the hood of the TableRow component to see how to generate the links to each order page. &lt;br&gt;
In line 6 , I de-structure the order object passed to this Component as props. In line 34 , I use the number key and interpolation to generate a URL for each order. If the order number for this Table Row is 1011 , then the URL will be "/orders/1011".&lt;br&gt;
Now that we have links for each order and a destination, we need some way to inform the OrderNumberPage which order information to display.&lt;/p&gt;

&lt;h2&gt;
  
  
  useParams Hook
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3nvaaoyl0rkeofurp8ty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3nvaaoyl0rkeofurp8ty.png" alt="useParams Hook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Import the useParams hook into the OrderNumberPage component. The useParams hook returns an object with key/value pairs , one of them being the unique identifier orderNumber we setup earlier. &lt;br&gt;
In line 9 , I assign the variable params to useParams(). params.orderNumber will allow us to access the URL parameter &lt;strong&gt;:orderNumber&lt;/strong&gt; from the current route. If we click on the link for order 1011, the params.orderNumber will return 1011. &lt;br&gt;
We'll use this value to find the order whose order number matches params.orderNumber , and in line 12 , filter it out of the list of orders. We then display the information for this specific order in the OrderNumberPage component. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rtlaxo8ccj8beukzfc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rtlaxo8ccj8beukzfc4.png" alt="Order Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We've setup a dynamic route with a unique URL parameter. We used React's useParams hook and our unique parameter to access a value , which we used to display specific information in our component. Using dynamic routing , we've created a consistent and predictable user experience. We've made our user's life much easier because the functionality of our app is predictable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nickmendezFlatiron/Order-Pro" rel="noopener noreferrer"&gt;Here's a link to the Order Pro repo if you'd like to check it out. &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Resource Recommendations&lt;br&gt;
&lt;a href="https://www.amazon.com/How-Customers-Think-Essential-Insights/dp/1578518261" rel="noopener noreferrer"&gt;How Customers Think - Gerald Zaltman &lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>ux</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Signals : A Simple Stock Market App</title>
      <dc:creator>Nicholas Mendez</dc:creator>
      <pubDate>Sun, 27 Mar 2022 21:37:51 +0000</pubDate>
      <link>https://forem.com/nickmendez/signals-a-simple-stock-market-app-1b5g</link>
      <guid>https://forem.com/nickmendez/signals-a-simple-stock-market-app-1b5g</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/nickmendezFlatiron/Signals" rel="noopener noreferrer"&gt;Signals&lt;/a&gt; began as a lofty idea to develop a platform for users who want to create and implement automated trade strategies, much like trading bots. Being quickly grounded by own coding ability, I shifted my focus on creating a beginner-friendly stock market tool, with room to develop. Just as I am very new to software engineering, there are many stock market novices who want to learn how trade stocks. &lt;br&gt;
Even the entry level market tools available seem intimidating for a trading newbie. After looking through different trading and analysis platforms such as Tradingview, Yahoo Finance, and Bloomberg, I found a few  fundamental components and packaged them into a less intimidating tool. I combined these tools, which provide relevant information to analyzing any market or security. These components are stock quotes, a market keyword search function, a watchlist, technical charting, a trade simulator, a portfolio manager, and trade transaction history. &lt;strong&gt;Signals.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftof2ufd0qfwjz2h2x0yl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftof2ufd0qfwjz2h2x0yl.png" alt="Signals Interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Signals Homepage&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I built signals with Javascript , using the Alpha Vantage API as a data source and Bootstrap 5 CDN for CSS styling. The Alpha Vantage API offers much more financial data than I needed, which allows for future additions and updates to Signals. &lt;br&gt;
The most difficult challenge was creating "My Portfolio" , a stock portfolio based on the user's trade history. Keeping the target user in mind, I developed a simplified trading system. The trading system is simplified to only allow &lt;a href="https://www.investopedia.com/ask/answers/100314/whats-difference-between-long-and-short-position-market.asp" rel="noopener noreferrer"&gt;Long and Short trade positions&lt;/a&gt;. The user cannot hold opposing positions of the same stock (a form of &lt;a href="https://www.investopedia.com/trading/hedging-beginners-guide/" rel="noopener noreferrer"&gt;hedging&lt;/a&gt;). Trades are taken at current market price of the traded asset. &lt;strong&gt;Here's how I turned a combination of both user inputs and API requests into an automated, up-to-date stock portfolio.&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Overview
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Provide the user with relevant information to make educated trading decisions.&lt;/li&gt;
&lt;li&gt;Allow the user to either buy or sell any amount of 
shares for any given ticker symbol. Collect the trade 
information every time a user executes a trade and store it 
somewhere.&lt;/li&gt;
&lt;li&gt;Use the stored data (trade history) to build the user's 
portfolio, also determining whether the user's position type in 
a given stock.
&lt;/li&gt;
&lt;li&gt;Legibly display the user's portfolio.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: Some basic understanding of Javascript is required to follow along with the code snippets provided and technical functionality.&lt;/p&gt;
&lt;h4&gt;
  
  
  1. Providing the User with A Stock Quote
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Signals fetches a quote from the Alpha Vantage API and displays it to the user.&lt;/strong&gt; Alpha Vantage uses different API functions, which determine the type of data is returned. The Quote Endpoint API function, which returns a detailed stock quote , requires a symbol, formally known as a ticker. A ticker is a letter abbreviation that acts as an identification code, specific to a traded stock or security on the market. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://www.alphavantage.co/query?function=GLOBAL_QUOTE&amp;amp;symbol=SYMBOLHERE&amp;amp;apikey=demo&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h6&gt;
  
  
  Quote Endpoint API URL
&lt;/h6&gt;
&lt;/blockquote&gt;

&lt;p&gt;This presents challenge 1; &lt;em&gt;what happens if I don't know the symbol?&lt;/em&gt; Fortunately, Alpha Vantage has a Search Endpoint API function , which returns the best-matching symbols based on keywords of your choice.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://www.alphavantage.co/query?function=SYMBOL_SEARCH&amp;amp;keywords=KEYWORDSHERE&amp;amp;apikey=demo&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h6&gt;
  
  
  Search Endpoint API Function URL
&lt;/h6&gt;
&lt;/blockquote&gt;

&lt;p&gt;Capture the user's keywords with a form input named search bar, replace "KEYWORDSHERE" in the Search Endpoint URL with the user input, display a list of best matching symbols, and select the desired symbol from the list. Simple enough.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;searchBtn.addEventListener('click',e =&amp;gt; {
  e.preventDefault()
  const searchbarValue = searchbar.value 
  let url = `https://www.alphavantage.co/query?function=SYMBOL_SEARCH&amp;amp;keywords=${searchbarValue}&amp;amp;apikey=VXY7DLJ0XAQQON66`
  marketSearch(url)
})

function marketSearch(url)  {
  fetch(url)
    .then(res =&amp;gt; res.json())
    .then(searchresults =&amp;gt; {
      let bestMatchesArray = (Object.values(searchresults))[0]
      searchResultsMatches = []
      bestMatchesArray.map(bestMatch =&amp;gt; simpleResults(bestMatch))
      appendResults(searchResultsMatches)
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7056t6u4727r903h5m3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7056t6u4727r903h5m3g.png" alt="Searchbar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With an event listener added to the search bar , Signals captures the user input and creates a usable url for the Search Endpoint API fetch request. The best matching companies are found with the marketSearch(url) function.&lt;br&gt;
SimpleResults function cleans up the data from the fetch request and appends each match to the searchResultsMatches array. The appendResults function creates a legible list , which appends each search result stored in the searchResultsMatches array to the DOM (specifically the Toolbox Display), in a legible unordered list. Each list item is given an id , which is the ticker symbol of that specific search result. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyyzc25zehi2zud3mpz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyyzc25zehi2zud3mpz9.png" alt="searchResultsMatchesArray"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h6&gt;
  
  
  searchResultsMatches Array with the user keyword AAPL
&lt;/h6&gt;
&lt;/blockquote&gt;

&lt;p&gt;A click event listener is added to each list item, and the id of that event target (the ticker symbol) is used to create the Quote Endpoint API URL. Now Signals can use the results of the Search Endpoint API request to build a URL for the Quote Endpoint API Request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function appendDisplay(e) {
  e.stopPropagation()
  let url = `https://www.alphavantage.co/query?function=GLOBAL_QUOTE&amp;amp;symbol=${e.target.id}&amp;amp;apikey=VXY7DLJ0XAQQON66`
  fetchStockData(url)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;appendDisplay(e) function is called every time a click event fires from any given list item appended via appendResults function previously mentioned&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The appendDisplay(e) function calls 2 other functions , organizeStockData(data) and printToDOM(stockDataObj).&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function fetchStockData(url){
  fetch(url)
    .then(res =&amp;gt; res.json())
    .then(data =&amp;gt; {organizeStockData(data)
      printToDOM(stockDataObj)
    }) 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;organizeStockData cleans up and organizes the data returned from a promise and creates stockDataObj. stockDataObj is then used by printToDOM to display a relevant stock quote to the user.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Creating a Trade Simulator
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Collecting The User Trade Data
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fppg9lbecwu78h9qjms2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fppg9lbecwu78h9qjms2a.png" alt="Main Display"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h6&gt;
  
  
  Main Display(left) shows the result of calling printTODOM, Search Results(right) displays the results of calling marketSearch function
&lt;/h6&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Main Display now displays actionable metrics used to speculate on the market and thus, execute trades. The righthand side of the Main Display shows all final information for a specific stock on the specified trading day. The lefthand graph displays intraday price movement and allows for technical charting with live data via Tradingview Widget. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5x0cl01g0sxyug5qkkcm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5x0cl01g0sxyug5qkkcm.png" alt="Sell or Buy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Making use of an input element and a select element, Signals can capture 2 user inputs, which will later be used to create the trade history. The input allows Signals to capture the quantity of shares for a specific trade , and the select options determine whether the shares are being sold or bought. &lt;/p&gt;

&lt;h5&gt;
  
  
  Storing The User Trade Data
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo84rbzhly7utk7q30kof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo84rbzhly7utk7q30kof.png" alt="Trade Transaction Function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every trade is then stored in a local database file db.json array "trade-history". &lt;/p&gt;

&lt;p&gt;The variable tradeQuantity selects the input we created with printTODOM , which captures the quantity of shares the user will be  trading. Variable tradeOptions refers to the select element with the type of trade the user is exercising (Buy or Sell).&lt;/p&gt;

&lt;p&gt;An event listener is added to tradeQuantity , specifically a keypress event. Once the event is fired, object newTrade is created. Using the stockDataObj made earlier, Signals stores a few different key/value pairs in newTrade. newTrade now holds the price of the traded symbol, date of the trade , ticker symbol traded, the trade type, and quantity of shares traded. All of this information is relevant to the user for refining trade strategies. &lt;br&gt;
Not every keypress event creates meaningful trade. I used if then statements to determine when it should post newTrade in the "trade-history".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vy2hrlo61yq1fnc5uy5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vy2hrlo61yq1fnc5uy5.png" alt="Localhost Database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"trade-history" updates when the keypress event is fired by the enter button , and the quantity of shares is positive. Then, newTrade is posted to the "trade-history" database, and the user is alerted that their trade was successful. Any unsuccessful trade prompts an alert message, informing the user to enter a positive integer in tradeQuantity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farr358yvzxy2dyaznp55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farr358yvzxy2dyaznp55.png" alt="Successful Trade"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function updateDatabase (newTrade, db = 'trade-history') {
  fetch(`http://localhost:3000/${db}`, {
    method: 'POST' ,
    headers: {
      'Content-Type': 'application/json'
    } ,
    body: JSON.stringify(newTrade)
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;updateDatabase sends a post request to a specified database in the JSON array. In this instance, the request is sent to &lt;a href="http://localhost:3000/trade-history" rel="noopener noreferrer"&gt;http://localhost:3000/trade-history&lt;/a&gt; updating "trade-history" with newTrade, the trade executed by the user. Signals is ready to make a stock portfolio from all the trades, based on the simplified trading system I created. &lt;/p&gt;

&lt;h4&gt;
  
  
  3. Reducing Trade History to a clean Portfolio.
&lt;/h4&gt;

&lt;p&gt;You may noticed I forgot to mention the function called within the if statement "fetchDatabase("trade-history",makePortfolio)". This function is responsible for turning the data stored in "trade-history" into a Portfolio of current user positions. Argument 2 is a function, which passes the converted JSON object (watchlistObj) as an argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function fetchDatabase(db,funct) {
  fetch(`http://localhost:3000/${db}`)
  .then(res =&amp;gt; res.json())
  .then(watchlistObj =&amp;gt; {
    funct(watchlistObj)
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Function makePortfolio uses a reduce method to return the &lt;br&gt;
accumulated results in a new array.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fky6dqpqppmzu74nxwjwu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fky6dqpqppmzu74nxwjwu.png" alt="makePortfolio Function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function accumulates all trades by the symbol , stored in the variable reducer. If the trade's type is "Buy" ,then the quantity of shares is added to the existing shares for that specific symbol. If the trade's type is "Sell" , then the quantity of shares is subtracted. If there is only one trade with for a specific symbol, then it is appended as-is , with all "Sell" trades stored with negative quantities. The accumulated result is a reduced array with only 1 array index per symbol. This will be stored in the db.json file as "portfolio".&lt;br&gt;
First, the existing "portfolio" data is cleared with a DELETE request by calling the function fetchDatabase('portfolio',clearPortfolio).&lt;br&gt;
Again, an array method is used to recategorize each index element in reducer. Every element with a negative quantity is stored as a "Short" trade , and every positive quantity is stored as a "Long" trade. &lt;/p&gt;
&lt;h4&gt;
  
  
  4. Append My Portfolio to DOM
&lt;/h4&gt;

&lt;p&gt;"portfolio" is displayed as table in the DOM. Function appendPortfolio is another function with one argument. Reusing the fetchDatabase function , appendPortfolio passes the JSON converted object from "portfolio" , and appends each element in a legible manner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function appendPortfolio(portfolioObj) {
  portfolioTableBody.innerHTML = ''
  portfolioObj.forEach(stock =&amp;gt; {
    let tr = document.createElement('tr')
    if(stock.quantity &amp;gt; 0) {
      tr.innerHTML = `
    &amp;lt;th scope="row"&amp;gt;${stock.symbol}&amp;lt;/th&amp;gt;
    &amp;lt;td class="text-success"&amp;gt;${stock.type}&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;${stock.quantity}&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;${stock.price}&amp;lt;/td&amp;gt;
    `
    } else if(stock.quantity &amp;lt; 0)
    tr.innerHTML = `
    &amp;lt;th scope="row"&amp;gt;${stock.symbol}&amp;lt;/th&amp;gt;
    &amp;lt;td class="text-danger"&amp;gt;${stock.type}&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;${(stock.quantity * -1)}&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;${stock.price}&amp;lt;/td&amp;gt;
    ` 
    portfolioTableBody.appendChild(tr)
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;portfolioTableBody is a global variable , which uses a querySelector to select the table in my HTML file that will display the data that makes My Portfolio.&lt;br&gt;
Long position types are styled with green text, and Short position types are style with red text. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felmzqg8cvbhxy58cwzp8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felmzqg8cvbhxy58cwzp8.png" alt="appendPortfolio result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I added a refresh button to the table which fires a click event, allowing the user to call appendPortfolio function at will. &lt;/p&gt;

&lt;p&gt;And thus, Signals was built. &lt;br&gt;
&lt;a href="https://github.com/nickmendezFlatiron/Signals" rel="noopener noreferrer"&gt;Feel free to explore Signals for yourself&lt;/a&gt;. Leave a comment for any features recommendations , improvements, or code refactors you may have. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus points if you know what I used to make the "i" in the Signals logo.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>4 Ways House Music Taught Me to Code</title>
      <dc:creator>Nicholas Mendez</dc:creator>
      <pubDate>Sat, 19 Mar 2022 17:46:37 +0000</pubDate>
      <link>https://forem.com/nickmendez/4-ways-house-music-taught-me-to-code-ah3</link>
      <guid>https://forem.com/nickmendez/4-ways-house-music-taught-me-to-code-ah3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Before joining Flatiron Software Engineering program, I wore a few different hats&lt;/strong&gt;. Graphic designer, day trader , branding manager, digital marketer , and my favorite, music producer. Just to name a few. &lt;br&gt;
They all have indirectly contributed to my growth as a software engineer. But music production has made the path of software engineering feel very familiar. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For context&lt;/strong&gt;. Let's rewind to May of 2016. I graduate from university with a BA in Economics, with no ambition to pursue the career path I spent the last 4 years building. My greatest fear is of regret. The life-long regret I'd experience if I never pursue my passion of becoming a music producer. For the next 4 years , I learned the ins and outs of EDM music production. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's how my affinity for house music has prepared me to become a software engineer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8agqq60j6a3xzulsukwe.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8agqq60j6a3xzulsukwe.gif" alt="Ableton Live &amp;amp; VSC"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 | Workspace and Workflow&lt;/strong&gt;&lt;br&gt;
Just like code editing, there are a few industry standard workspaces to choose from. My DAW (digital audio workspace) of choice is Ableton Live. For code editing, I prefer Visual Studio Code. Both interfaces are very similar. Folder and file management exists on the left-hand side. The main display is used for building and arrangement. This area is a visual representation of the actual project you are creating, including its molecular anatomy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2 | Task Packaging&lt;/strong&gt;&lt;br&gt;
Mix Busing and effect chains in Ableton are much like algorithms and functions. Effect chains and buses group a set of effects, or ways to manipulate a sound (data) , in a specific sequence which produces a new sound. The predictability of the chain is dependent on the effects used. Mix busing is normally used as a tool to merge multiple tracks into one, to make them sound cohesive. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3 | Information Manipulation&lt;/strong&gt;&lt;br&gt;
At its simplicity, sound is a form of data interpreted by our hearing faculties. Much like any coding language, Ableton provides many tools to manipulate this data. Ableton allows for looping specific sections of a song, parameter automation, file linking , and much more. You can even create your own tools to implement across different projects. Very similar to a script library.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 | Learning&lt;/strong&gt;&lt;br&gt;
This section is much less about the actual tools , and more about the process of mastery in both endeavors. I have spent thousands of hours in Ableton, production forums , Youtube tutorials , and communities learning and sharpening my abilities as a producer. Most of us are fortunate enough to have the answer to every question through the power of the internet. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The greatest takeaway from music production I have is to finish out every project you start. Your first projects are not going to be a home run, and that's okay. Learning to start and finish a project is an important skill all in itself&lt;/strong&gt;.There was a time where I'd create a 16 bar loop in Ableton, and it would sound amazing. But I'd get stuck and move onto another idea. I had all of these great loops, but no finished songs. Finishing a project is a skill that requires training. The only way to create your 50th app is to create 49 more before it.&lt;/p&gt;

&lt;p&gt;I'm sure the parallels between music production and coding will continue to develop as my experience as a software engineer develops. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>writing</category>
    </item>
  </channel>
</rss>
