<?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>DEV Community: andrewjpwalters</title>
    <description>The latest articles on DEV Community by andrewjpwalters (@andrewjpwalters).</description>
    <link>https://dev.to/andrewjpwalters</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F830758%2F259f93c5-d85b-4e24-8a16-3e06855a1807.png</url>
      <title>DEV Community: andrewjpwalters</title>
      <link>https://dev.to/andrewjpwalters</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andrewjpwalters"/>
    <language>en</language>
    <item>
      <title>Using Active Storage with Amazon S3 and React</title>
      <dc:creator>andrewjpwalters</dc:creator>
      <pubDate>Thu, 04 May 2023 09:30:51 +0000</pubDate>
      <link>https://dev.to/andrewjpwalters/using-active-storage-with-amazon-s3-and-react-31gb</link>
      <guid>https://dev.to/andrewjpwalters/using-active-storage-with-amazon-s3-and-react-31gb</guid>
      <description>&lt;p&gt;In this blog post, we'll explore how to use Active Storage with Amazon S3 to store image files and how to use React to display those images in a web application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Amazon S3
&lt;/h2&gt;

&lt;p&gt;The first step is to create an Amazon S3 bucket to store your image files. To do this, log in to your Amazon Web Services (AWS) account and navigate to the S3 dashboard. From there, click on the "Create bucket" button and follow the prompts to create your bucket.&lt;/p&gt;

&lt;p&gt;Once your bucket is created, you'll need to generate an access key and secret key for your AWS account. These credentials will be used by Rails to access your S3 bucket. To generate your credentials, navigate to the AWS Identity and Access Management (IAM) dashboard and create a new user. Make sure to give the user the appropriate permissions to access your S3 bucket.&lt;/p&gt;

&lt;p&gt;Once your bucket is set up, you will also want to add the following permission object into the CORS (Cross-origin resource sharing) configuration in your bucket settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up Active Storage
&lt;/h2&gt;

&lt;p&gt;The next step is to set up Active Storage in your Rails application. To do this, first, add the following line to your Gemfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem 'aws-sdk-s3'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install the necessary dependencies for using Active Storage with Amazon S3.&lt;/p&gt;

&lt;p&gt;Next, run the following command to set up Active Storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails active_storage:install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a migration that adds the necessary tables to your database.&lt;/p&gt;

&lt;p&gt;Run the migration with the following command:&lt;br&gt;
&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;You will also need to uncomment Amazon storage code in your storage.yml file and fill in the appropriate data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amazon:
  service: S3
  access_key_id: &amp;lt;%= Rails.application.credentials.dig(:aws, :access_key_id) %&amp;gt;
  secret_access_key: &amp;lt;%= Rails.application.credentials.dig(:aws, :secret_access_key) %&amp;gt;
  region: your-region
  bucket: your-bucket-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, with this command you will be able to edit your credential files and include the access key and secret access key provided by AWS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EDITOR="code --wait" rails credentials:edit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your development.rb file in your environments, you will also need to change your config.active_storage.service to Amazon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.active_storage.service = :amazon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, in your initializers, in your cors.rb file, uncomment out the necessary code, and change the origins to whatever your project requires. For the sake of this example, a wildcard will be included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that Active Storage is set up, we can start using it to store our image files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uploading Files
&lt;/h2&gt;

&lt;p&gt;To upload an image file, first, create a form in your React application that allows users to select a file to upload. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';

function ImageUploadForm() {
  const [file, setFile] = useState(null);

  function handleChange(event) {
    setFile(event.target.files[0]);
  };

  function handleSubmit(event) {
    event.preventDefault();
    const formData = new FormData();
    formData.append('image', file);

    fetch('/images', {
      method: 'POST',
      body: formData,
    });

    if (response.ok) {
      console.log('Image uploaded successfully');
    } else {
      console.log('Error uploading image');
    }
  };

  return (
    &amp;lt;form onSubmit={handleSubmit}&amp;gt;
      &amp;lt;input type="file" onChange={handleChange} /&amp;gt;
      &amp;lt;button type="submit"&amp;gt;Upload Image&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
}

export default ImageUploadForm;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This form will allow users to select an image file to upload. Note that images must be appended to a new FormData as the information can not be sent as JSON. &lt;/p&gt;

&lt;p&gt;Next, create a Rails controller action to handle the file upload. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ImagesController &amp;lt; ApplicationController
  def create
    image = Image.new(image_params)
    if image.save
      render json: { image_url: url_for(image.image) }, status: :created
    else
      render json: image.errors, status: :unprocessable_entity
    end
  end

  private

  def image_params
    params.permit(:image)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This controller action creates a new &lt;code&gt;Image&lt;/code&gt; object and assigns it the uploaded file. The &lt;code&gt;image_params&lt;/code&gt; method is used to permit only the &lt;code&gt;image&lt;/code&gt; parameter to be passed to the &lt;code&gt;Image&lt;/code&gt; model. The response includes the URL of the uploaded image, which we'll use in the React application to display the image.&lt;/p&gt;

&lt;p&gt;Another way to access the image’s url is to define the image_url in the serializer. Here’s an example for that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ImageSerializer &amp;lt; ActiveModel::Serializer
  include Rails.application.routes.url_helpers

  attributes :id, :image_url

  def image_url
    if object.image.attached?
      url_for(object.image)
    else
      ""
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the line “include Rails.application.routes.url_helpers” must be included to have access to the url_for helper.&lt;/p&gt;

&lt;p&gt;Next, add the following code to your &lt;code&gt;Image&lt;/code&gt; model to use Active Storage to store the image file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Image &amp;lt; ApplicationRecord
  has_one_attached :image
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Displaying Files
&lt;/h2&gt;

&lt;p&gt;Now that we have uploaded our images to S3 using Active Storage, we can display them in our React application. Here's an example of how to display an image in React:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';

function ImageDisplay({ imageUrl }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;img src={imageUrl} alt="Uploaded Image" /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default ImageDisplay;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component takes the URL of the image as a prop and displays it using an &lt;code&gt;img&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;Finally, we can use our &lt;code&gt;ImageUploadForm&lt;/code&gt; and &lt;code&gt;ImageDisplay&lt;/code&gt; components together to create a complete image upload and display feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';
import ImageUploadForm from './ImageUploadForm';
import ImageDisplay from './ImageDisplay';

function App() {
  const [imageUrl, setImageUrl] = useState(null);

  function handleImageUpload(formData) {
    fetch('/images', {
      method: 'POST',
      body: formData,
    });

    if (response.ok) {
      r.json().then((data) =&amp;gt; setImageUrl(data.image_url));
    } else {
      console.log('Error uploading image');
    }
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;ImageUploadForm onImageUpload={handleImageUpload} /&amp;gt;
      {imageUrl &amp;amp;&amp;amp; &amp;lt;ImageDisplay imageUrl={imageUrl} /&amp;gt;}
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component creates an &lt;code&gt;ImageUploadForm&lt;/code&gt; and an &lt;code&gt;ImageDisplay&lt;/code&gt; component. When an image is uploaded, the &lt;code&gt;handleImageUpload&lt;/code&gt; function is called, which sends a POST request to the Rails API and sets the &lt;code&gt;imageUrl&lt;/code&gt; state to the URL of the uploaded image. The &lt;code&gt;ImageDisplay&lt;/code&gt; component is only shown if &lt;code&gt;imageUrl&lt;/code&gt; is not null.&lt;/p&gt;

&lt;p&gt;And that's it! You should now have a fully functioning image upload and display feature in your React application using Active Storage with Amazon S3.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Active Record Validations</title>
      <dc:creator>andrewjpwalters</dc:creator>
      <pubDate>Fri, 21 Apr 2023 09:02:28 +0000</pubDate>
      <link>https://dev.to/andrewjpwalters/active-record-validations-22e1</link>
      <guid>https://dev.to/andrewjpwalters/active-record-validations-22e1</guid>
      <description>&lt;p&gt;One of the key features of Ruby on Rails is its powerful Active Record ORM (Object Relational Mapping) layer, which abstracts away the details of database access and allows you to work with your data in a more object-oriented way. One of the most important features of Active Record is its support for validations, which allow you to ensure that the data stored in your database is always consistent, accurate, and valid.&lt;/p&gt;

&lt;p&gt;What are Active Record Validations?&lt;/p&gt;

&lt;p&gt;Active Record validations live on the model layer of Rails, which is structured on the MVC architecture. They are a way to check that the data stored in your database is always valid and consistent. They allow you to define rules or constraints on the data, and then check that those rules are being followed whenever you try to save or update an object to the database. For example, you might want to ensure that a user's email address is unique, or that a blog post's title is at least 5 characters long.&lt;/p&gt;

&lt;p&gt;Active Record provides a wide range of built-in validation helpers that make it easy to define these rules. Some of the most common validation helpers include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;presence: ensures that a field is not empty or nil&lt;/li&gt;
&lt;li&gt;uniqueness: ensures that a field is unique across all records in the table&lt;/li&gt;
&lt;li&gt;numericality: ensures that a field is a number&lt;/li&gt;
&lt;li&gt;length: ensures that a field is a certain length&lt;/li&gt;
&lt;li&gt;format: ensures that a field matches a certain regular expression&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When are Active Record Validations Run?&lt;/p&gt;

&lt;p&gt;Active Record validations are run automatically whenever you try to save or update an object to the database using the save, create or update methods. When you call one of these methods, Active Record first checks that all the validations defined for the object pass. If any of the validations fail, the operation is cancelled and the object is not saved to the database.&lt;/p&gt;

&lt;p&gt;For example, let's say you have a User model with a name field that must be present. You might define a validation like this:&lt;br&gt;
&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
  validates :name, presence: true
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if you try to save a User object without a name, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user = User.new
user.save!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The save method will return false, indicating that the object was not saved, and, by using the bang version of save, an exception will be raised and the errors object on the User object will contain an error message indicating that the name field must be present. The same is true for the bang version of create and update. &lt;/p&gt;

&lt;p&gt;In addition to running validations when you save an object, you can also manually trigger validations on an object by calling the valid? method. This method runs all the validations for the object and returns true if all validations pass, or false if any of them fail.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User.create(name: "Jane Johnson” ).valid?
=&amp;gt; true
User.create(name: nil).valid?
=&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In short, if you're new to Ruby on Rails like I am, learning how to use Active Record validations is essential. By mastering this feature, you'll be able to build more robust, secure, and user-friendly applications that store consistent and valid data. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Phase 4 Wrap Up and Utilizing useContext</title>
      <dc:creator>andrewjpwalters</dc:creator>
      <pubDate>Fri, 07 Apr 2023 21:04:40 +0000</pubDate>
      <link>https://dev.to/andrewjpwalters/phase-4-wrap-up-and-utilizing-usecontext-3p6d</link>
      <guid>https://dev.to/andrewjpwalters/phase-4-wrap-up-and-utilizing-usecontext-3p6d</guid>
      <description>&lt;p&gt;Phase 4 of my time at Flatiron School is coming to a close. I wrapped up my phase 4 final project, which was the biggest challenge I’ve faced as a new programmer to date. One of the requirements was the inclusion of the React hook, useContext. I’d never used this hook before, so it was an interesting challenge to learn how it works and to implement it into my project. &lt;/p&gt;

&lt;p&gt;What I found was that the useContext hook is a powerful tool in React that can simplify state management and make your code more organized and reusable. Together we'll explore what the useContext hook is, how it works, and how you can use it in your own React applications.&lt;/p&gt;

&lt;p&gt;What is the useContext hook?&lt;/p&gt;

&lt;p&gt;The useContext hook is a built-in React hook that allows you to access state and methods from a parent component in any child component without having to pass props down through each level of the component tree.&lt;/p&gt;

&lt;p&gt;When using the useContext hook, you create a context object that contains the shared state and methods you want to use across multiple components. Then, you can use the useContext hook to access that context object in any child component and use its state and methods.&lt;/p&gt;

&lt;p&gt;Here’s an example to show how the useContext hook works.&lt;/p&gt;

&lt;p&gt;Suppose you have a parent component called App that has a state variable called count and a method called incrementCount:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';

function App() {
  const [count, setCount] = useState(0);

  const incrementCount() {
    setCount(count + 1);
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={incrementCount}&amp;gt;Increment&amp;lt;/button&amp;gt;
      &amp;lt;ChildComponent /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we're using the useState hook to create a state variable called count and a method called setCount to update the count. We're also rendering a button that calls the incrementCount method when clicked.&lt;/p&gt;

&lt;p&gt;Now, suppose we have a child component called ChildComponent that needs access to the count and incrementCount variables. We could pass these variables down as props, but that would require us to pass them through every level of the component tree, which, I discovered, opens up your code to all kinds of headache inducing troubleshooting if you miss a step. Instead, we can use the useContext hook to access these variables directly.&lt;/p&gt;

&lt;p&gt;To use the useContext hook, we first need to create a context object in the parent component. We can do this using the createContext method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, createContext } from 'react';

const CountContext = React.createContext()

export const CountContext = createContext();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we're creating a context object called CountContext using the createContext method. We're exporting this object so that we can use it in other components.&lt;/p&gt;

&lt;p&gt;Next, we need to wrap our parent component with the CountContext.Provider component and pass it the count and incrementCount variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, createContext } from 'react';
import ChildComponent from './ChildComponent';

export const CountContext = createContext();

function App() {
  const [count, setCount] = useState(0);

  const incrementCount = () =&amp;gt; {
    setCount(count + 1);
  };

  return (
    &amp;lt;CountContext.Provider value={{ count, incrementCount }}&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
        &amp;lt;button onClick={incrementCount}&amp;gt;Increment&amp;lt;/button&amp;gt;
        &amp;lt;ChildComponent /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/CountContext.Provider&amp;gt;
  );
};

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we're wrapping the App component with the CountContext.Provider component and passing it an object with the count and incrementCount variables as values.&lt;/p&gt;

&lt;p&gt;Finally, in the ChildComponent, we can use the useContext hook to access the count and incrementCount variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useContext } from 'react';
import { CountContext } from './App';

function ChildComponent() {
  const { count, incrementCount } = useContext(CountContext);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={incrementCount}&amp;gt;Increment&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default ChildComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we're importing the CountContext object from the App component and using the useContext hook to access the count and incrementCount variables. We can then render these variables in the ChildComponent JSX and use the incrementCount method to update the count.&lt;/p&gt;

&lt;p&gt;By using the useContext hook, we're able to access shared state and methods without having to pass props down through every level of the component tree.&lt;/p&gt;

&lt;p&gt;One can also set state or even define the provider in the context file, as I did with my own project, to pass down user information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";

const UserContext = React.createContext();

function UserProvider({ children }) {
    const [user, setUser] = useState(null);
    return (
        &amp;lt;UserContext.Provider value={{ user, setUser }}&amp;gt;
            {children}
        &amp;lt;/UserContext.Provider&amp;gt;
    );
}

export { UserContext, UserProvider };

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

&lt;/div&gt;



&lt;p&gt;This way, I just needed to import UserContext and if I wanted, say, just the user variable, in any component I would declare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { user } = useContext(UserContext)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in the same way have access to the user variable.&lt;/p&gt;

&lt;p&gt;My instructor, when speaking to him, mentioned useContext was becoming quite popular and I now understand why. useContext is a powerful tool that requires minimal setup and makes your code more simple, and easier to understand and develop. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Phase 3 Project Wrap-up</title>
      <dc:creator>andrewjpwalters</dc:creator>
      <pubDate>Fri, 23 Sep 2022 05:55:28 +0000</pubDate>
      <link>https://dev.to/andrewjpwalters/phase-3-project-wrap-up-5c80</link>
      <guid>https://dev.to/andrewjpwalters/phase-3-project-wrap-up-5c80</guid>
      <description>&lt;p&gt;It’s time! I’m now finishing up my phase 3 final project at Flatiron School. In this phase we covered a lot of things: Ruby basics, the fundamentals of the backend of an app, Active Record and Sinatra. &lt;br&gt;
&amp;nbsp;&lt;br&gt;
Ruby is a pleasure to work with. I wonder if it would’ve been such a breeze to get into if I didn’t have any familiarity with JavaScript, but as it stands, its emphasis on clean readability is very welcome. I appreciate Yukihiro Matsumoto’s desire to make programmers happy and, although I am a newcomer to this field and especially to this language, I think I can see why it’s such a popular language.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
Working with Active Record was also refreshing. As always, I appreciate learning how to do something the hard way before learning the shortcut—or in this case, the modern, efficient way. The same goes for Sinatra. Sometimes I feel like I’m cheating, knowing how many steps are automated by these wonderful tools. &lt;br&gt;
&amp;nbsp;&lt;br&gt;
The guidelines for this project were relatively straightforward, building on the things we’d learned in the past phases—particularly React and assembling frontend applications. I was required to: Use Active Record to start a database with at least two models with a one-to-many relationship, use Sinatra to set up API routes for both models (with create and read actions for both and one with full CRUD), and, as I stated, create a front end with React to interact with the API and utilize those CRUD capabilities. &lt;br&gt;
&amp;nbsp;&lt;br&gt;
I was at a bit of a loss of what to create that would hit all these guidelines and still be an app I could see using, and finally I settled on my reliable love of film to provide an answer: A movie watchlist, where the user can add films they would like to watch and filter them by genre. Genre and movie would be my two models, with MANY movies belonging to ONE genre. The movies model ended up being the one receiving full CRUD—the ability to create new movies, as well as list all the movies saved, edit any comments left on the individual movies as well as delete them from the database. &lt;br&gt;
&amp;nbsp;&lt;br&gt;
First, I created a very simple framework of a React application, setting up the very basic components I would need. But I could only go so far without any information to feed through an API. So, I had to create one. &lt;br&gt;
&amp;nbsp;&lt;br&gt;
To set up these models I called on the ever-handy Rake:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle exec rake db:create_migration NAME=create_movies
bundle exec rake db:create_migration NAME=create_genre
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;br&gt;
These lines called on Active Record to create two migrations, one for a movies table and one for a genres table. From there I defined the rows for movies:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CreateMovies &amp;lt; ActiveRecord::Migration[6.1]
&amp;nbsp; def change
&amp;nbsp;&amp;nbsp;&amp;nbsp; create_table :movies do |t|
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.string :name
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.integer :genre_id
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.integer :year
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.string :comment
&amp;nbsp;&amp;nbsp;&amp;nbsp; end
&amp;nbsp; end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;br&gt;
And for genres:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CreateGenres &amp;lt; ActiveRecord::Migration[6.1]
&amp;nbsp; def change
&amp;nbsp;&amp;nbsp;&amp;nbsp; create_table :genres do |t|
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.string :name
&amp;nbsp;&amp;nbsp;&amp;nbsp; end
&amp;nbsp; end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;br&gt;
From there I had to write my models and establish their association. Once again, Active Record made it shockingly easy, utilizing the has_many and belongs_to macros :&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Movie &amp;lt; ActiveRecord::Base
&amp;nbsp;&amp;nbsp;&amp;nbsp; belongs_to :genre
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;br&gt;
And for genres:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Genre &amp;lt; ActiveRecord::Base
&amp;nbsp;&amp;nbsp;&amp;nbsp; has_many :movies
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;br&gt;
And that was it for Active Record! I just had to create my migration:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle exec rake db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;br&gt;
And my schema was created and ready to be populated with date! After installing Faker, I filled the seed.rb with some randomized movie data and provide a strong base of genres to get started with. &lt;br&gt;
&amp;nbsp;&lt;br&gt;
Next Sinatra came into play, and this is where I started to hit some snags. Here I had to write my pathways and assign my models some CRUD. Because my two models were associated, I knew I needed to include a special keyword “includes” in my pathway definitions. That was simple enough when creating and reading for my models:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ApplicationController &amp;lt; Sinatra::Base
&amp;nbsp; set :default_content_type, 'application/json'
&amp;nbsp; 
&amp;nbsp; get "/movies" do
&amp;nbsp;&amp;nbsp;&amp;nbsp; movies = Movie.all.order(:name)
&amp;nbsp;&amp;nbsp;&amp;nbsp; movies.to_json(include: :genre)
&amp;nbsp; end
&amp;nbsp;
&amp;nbsp; get "/genres" do
&amp;nbsp;&amp;nbsp;&amp;nbsp; genres = Genre.all.order(:name)
&amp;nbsp;&amp;nbsp;&amp;nbsp; genres.to_json(include: :movies)
&amp;nbsp; end
&amp;nbsp;
&amp;nbsp; post "/movies" do
&amp;nbsp;&amp;nbsp;&amp;nbsp; movie = Movie.create(name: params[:name], genre_id: params[:genre_id], year: params[:year], comment: params[:comment])
&amp;nbsp;&amp;nbsp;&amp;nbsp; movie.to_json(include: :genre)
&amp;nbsp; end
&amp;nbsp;
&amp;nbsp; post "/genres" do
&amp;nbsp;&amp;nbsp;&amp;nbsp; genre = Genre.create(name: params[:name])
&amp;nbsp;&amp;nbsp;&amp;nbsp; genre.to_json(include: :movies)
&amp;nbsp; end
&amp;nbsp;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;br&gt;
But for some reason, when it came to writing my patch and delete methods, I kept getting strange errors and my React application would break. The strangest thing is I was getting no errors from my API. Only from React. When I would refresh the page, the changes I’d made—whether a deleted movie or patched comment—would be rendered just fine. It was only during the act of rendering those changes in my front end application would the app break. My first clue was that trying to access the genre name through each movie, rather than the genre_id property, and the error would tell me it didn’t recognize “genre” and would declare it undefined. Although it didn’t occur to me at first, I once again had to include the associated model in my pathway definition. For some reason, I seemed to think that information was already packaged with the instance once it was created. But once I added that all important “include” keyword, the errors went away:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;nbsp; patch "/movies/:id" do
&amp;nbsp;&amp;nbsp;&amp;nbsp; movie = Movie.find(params[:id])
&amp;nbsp;&amp;nbsp;&amp;nbsp; movie.update(comment: params[:comment])
&amp;nbsp;&amp;nbsp;&amp;nbsp; movie.to_json(include: :genre)
&amp;nbsp; end
&amp;nbsp;
&amp;nbsp; delete "/movies/:id" do
&amp;nbsp;&amp;nbsp;&amp;nbsp; movie = Movie.find(params[:id])
&amp;nbsp;&amp;nbsp;&amp;nbsp; movie.destroy
&amp;nbsp;&amp;nbsp;&amp;nbsp; movie.to_json(inlude: :genre)
&amp;nbsp; end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;br&gt;
It took me longer than I would care to admit to solve this in-retrospect simple problem, but once I got it up and working, the struggle and headache was worth it. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>My Phase 2 Project and Working with React Bootstrap</title>
      <dc:creator>andrewjpwalters</dc:creator>
      <pubDate>Fri, 29 Jul 2022 02:11:39 +0000</pubDate>
      <link>https://dev.to/andrewjpwalters/my-phase-2-project-and-working-with-react-bootstrap-19kg</link>
      <guid>https://dev.to/andrewjpwalters/my-phase-2-project-and-working-with-react-bootstrap-19kg</guid>
      <description>&lt;p&gt;It looks like my phase 2 at Flatiron School is coming to a close. This phase was all about React, which I enjoyed quite a bit. There's always something exhilarating and, at the same time, a little exasperating about learning a "shortcut" after taking the time to learn something the hard way. One, of course, must learn the fundamentals before learning how to break them, so there's no misunderstanding there. But React, at the surface, certainly feels like a "shortcut" of sorts. A very welcome one at that.&lt;/p&gt;

&lt;p&gt;But no shortcut is ever completely clean and React has its quirks and oddities to make it work smoothly. Thankfully, the ever-helpful community of programmers have come up with a variety of packages to help make even this "shortcut" easier and friendlier to use.&lt;/p&gt;

&lt;p&gt;React Router is a great example, and one that I used extensively on this project. It gives functionality and illusion of paths in an SPA (single page application). Flatiron's curriculum taught React Router quite thoroughly, so I didn't have any issues implementing it.&lt;/p&gt;

&lt;p&gt;This was not the case when I decided to try Bootstrap with my application, my old standby which I used in my phase 1 project. I've always liked the ease and styling of Bootstrap, so I thought it would be a nice challenge to apply it to my first Javascript framework.&lt;/p&gt;

&lt;p&gt;I found during my research the perfect solution: React Bootstrap&lt;/p&gt;

&lt;p&gt;React Bootstrap, as the name would suggest, was built from scratch specifically for React, doing away with dependencies like jQuery, but still retaining the classic Bootstrap styling and functionality. &lt;/p&gt;

&lt;p&gt;Installing it was easy. After creating my app using &lt;code&gt;create-react-app&lt;/code&gt; I just had to installing it, also utilizing NPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install react-bootstrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The documentation suggest installing vanilla Bootstrap as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install bootstrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or you can combine both into a single line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install react-bootstrap bootstrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NPM will install both React Bootstrap and vanilla Bootstrap frameworks into your project as dependencies.&lt;/p&gt;

&lt;p&gt;Once that is done, because React Bootstrap doesn't automatically ship with Bootstrap CSS, you must include this import line at the top of either or src/index.js or App.js file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'bootstrap/dist/css/bootstrap.min.css';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will import all the styling you'll need to match React Bootstrap's blind spots.&lt;/p&gt;

&lt;p&gt;Next, you'll need to start importing the components you'll be using in your app. These include things like buttons, cards, navbars and tables. There are two ways of doing this, and one is recommended over the other. &lt;/p&gt;

&lt;p&gt;Firstly, and most simply, you can destructure out the component you need like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Button, Card, Navbar } from 'react-bootstrap';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the issue with this is it will instruct React to load the entire React Bootstrap library, potentially loading your app down and making it less efficient. &lt;/p&gt;

&lt;p&gt;Best practice is to import each component individually on separate lines, thus avoiding importing the entire library unnecessarily. You can do so like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Button from 'react-bootstrap/Button';
import Card from 'react-bootstrap/Card';
import Navbar from 'react-bootstrap/Navbar';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not quite as pretty or succinct as destructuring, but certainly more ideal. The way I approached it, and the way it was recommended to me, was to use the destructuring method while I was developing my app, being able to quickly and easily slot in and out components as I needed them. But as I neared the end of production and the needed components were solidified, I rewrote my code to the individual import method.&lt;/p&gt;

&lt;p&gt;Once these steps are done, you will be able to include these React Bootstrap components in the return of your own components just like any other JSX element.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import Button from 'react-bootstrap/Button';

function Example(){
return (
&amp;lt;h1&amp;gt;Hello!&amp;lt;/h1&amp;gt;
&amp;lt;Button&amp;gt;Click Me!&amp;lt;/Button&amp;gt;
)};

export default Example;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the issues I immediately ran across with React Bootstrap my app's usage of React Router. React Bootstrap has plenty of support for navbars, but React Router uses a specific &lt;code&gt;&amp;lt;Link&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;NavLink&amp;gt;&lt;/code&gt; element that React Bootstrap has no reference to. A quick Google search and I found the community has plenty to provide yet again. In came the extremely specific and extremely useful React Router Bootstrap to solve this problem.&lt;/p&gt;

&lt;p&gt;It's just as simple to install as all the others. One just needs to run this line if he or she is using the most current version of React Router:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -S react-router-bootstrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although, because I was specifically using React Router v5, I instead ran this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -S react-router-bootstrap@rr-v4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React Router Bootstrap was in my project, and then to get that nice Bootstrap styling in my navbar, I just needed to wrap each of my &lt;code&gt;&amp;lt;NavLink&amp;gt;&lt;/code&gt; elements in a React Router Bootstrap specific &lt;code&gt;&amp;lt;LinkContainer&amp;gt;&lt;/code&gt; tag, importing it at the top of my component page just as I did any of my React Bootstrap components.&lt;/p&gt;

&lt;p&gt;All this proves this community is constantly pushing and evolving to incorporate new technologies. Every issue I had, someone had already discovered a solution and presented it in a clean, understandable fashion. And when I ever felt confused, there were countless YouTube tutorials to fill in the gaps.&lt;/p&gt;

&lt;p&gt;Phase 2 is finished. On to the next.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Wrapping Up My First Project at Flatiron</title>
      <dc:creator>andrewjpwalters</dc:creator>
      <pubDate>Mon, 23 May 2022 03:55:22 +0000</pubDate>
      <link>https://dev.to/andrewjpwalters/wrapping-up-my-first-project-at-flatiron-539a</link>
      <guid>https://dev.to/andrewjpwalters/wrapping-up-my-first-project-at-flatiron-539a</guid>
      <description>&lt;p&gt;Here we are. I'm wrapping up m first major project at Flatiron School. Maybe this feeling won't fade away, but early in my software development journey, coding still feels a little like learning magic. That may sound silly but think of it this way: In books and movies, magic is expressed with words of power--with expressions and phrases that are filled with such potent meaning, they alter the world around them. With coding, you're using a language filled with words of power, that can alter the behavior of a computer, giving it instructions to do incredible things. Typing in the right words in the right order and somehow it &lt;em&gt;works&lt;/em&gt;. Your vision becomes reality. &lt;/p&gt;

&lt;p&gt;And in a more mundane way, learning to code is just like learning any other language. You learn the syntax and grammar, the meaning. Currently, I feel a little like I did in French class back in high school: I can read the language just fine. I can follow the logic and decipher the meaning, but when it comes to speaking it, much of the time, my mind just goes blank. I've been told many times that there's no shame in Googling answers to problems. Everyone does it all the time. But I do hope I manage to build the mental muscle memory for some of these simpler problems sooner rather than later.&lt;/p&gt;

&lt;p&gt;This first project was where I felt both feelings really clash for me. A sense of elation when, oh wow, the code I wrote worked! It was doing just what I envisioned! And a sense of dread when I would hit a roadblock in my knowledge or would see an error pop up while my website would refuse to do what I wanted it to do. But going back to the idea of Googling, I will say, the programming community has a willingness to share knowledge and an eagerness to help its fellows in a way I've never seen in any other community.&lt;/p&gt;

&lt;p&gt;Taking these steps, following the path laid by other programmers, I found my way through and around every roadblock I came across.&lt;/p&gt;

&lt;p&gt;First, I should probably lay out what the function of my project is: I found an API called TV Maze and decided to build a search that would fetch a list of TV shows from their database. The results of the search would be rendered as "cards" and appended to an empty element. Each card would have a button that would add the show to another section on the page called "Watch List." If I were to build a server myself, this would be accomplished with a POST request, but since the site didn't need to be persistent, I needed to find a way to clone the card to this watch list. Most of the objectives I needed to make this project a reality, I already had an idea of how to do. The means to clone elements, however, was something I need to figure out how to do from scratch.&lt;/p&gt;

&lt;p&gt;I went about writing the code for the things I already knew how to do: Making the bare bones of the HTML, adding important ids to elements I knew my script would be frequently working with through the DOM. Writing the FETCH request to interact with TV Maze's API, and the function to render the received data in HTML elements (This was tricky, and I ended up having to rely heavily on the innerHTML property, which I have since discovered has the potential to be a security risk; in the future, I will have to use other means to a achieve this), and the event listeners for the search input and the "Add to Watch List" buttons. When I got stuck, I referred to the videos and lessons Flatiron had provided on whatever subject I needed help with. And when I had nothing left to do, I had to confront the biggest blank in my knowledge: How to copy elements in the DOM. &lt;/p&gt;

&lt;p&gt;I was expecting a lot of finagling, but instead, it turned out good ol' Javascript had my back. I came across a node method called (wait for it) cloneNode. All I had to do was capture an element in the DOM, call this method and then append the cloned element wherever I wanted on the page. The only thing that threw me for a loop was an optional parameter in the method called "deep." When "true," it would copy the entire node, including its entire subtree (minus any event listeners). Otherwise, it would default to "false," and the node would be cloned, but it would be essentially empty. &lt;/p&gt;

&lt;p&gt;Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const el = document.querySelector('#example')

const elCopy = el.cloneNode(true)
elCopy.setAttribute('id', 'example2')
body.append(elCopy)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is an issue with cloning elements with ids, but any attribute, content, etc., can be modified by normal means before it is appended to the page, as seen above.&lt;/p&gt;

&lt;p&gt;Next, I had to learn the basics of Bootstrap because I decided I would challenge myself to learn a CSS framework. But perhaps I'll save that for another blog post.&lt;/p&gt;

&lt;p&gt;In any case, this first project is wrapping up and I'm ready to face my next challenge--whatever it may be.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
