<?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: nicklevenson</title>
    <description>The latest articles on DEV Community by nicklevenson (@nicklevenson).</description>
    <link>https://dev.to/nicklevenson</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%2F494396%2Fde155a13-9ef2-4732-ba46-be49fa8451db.jpeg</url>
      <title>DEV Community: nicklevenson</title>
      <link>https://dev.to/nicklevenson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicklevenson"/>
    <language>en</language>
    <item>
      <title>Requests and Connections like LinkedIn - How to Implement These Model Relationships in a Rails App</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Thu, 03 Jun 2021 20:15:25 +0000</pubDate>
      <link>https://dev.to/nicklevenson/requests-and-connections-like-linkedin-how-to-implement-these-model-relationships-in-a-rails-app-59on</link>
      <guid>https://dev.to/nicklevenson/requests-and-connections-like-linkedin-how-to-implement-these-model-relationships-in-a-rails-app-59on</guid>
      <description>&lt;p&gt;As part of a large project I have been working on, I wanted to allow users to request and accept connections from other users. Very similar to the way LinkedIn works, users could ask others to get connected and be connected with those users if the request was accepted. This proved to be a challenging, but fun exercise in model relationships in a Rails application. There are plenty of other ways to do this, but this is what worked well for me. &lt;/p&gt;

&lt;p&gt;First and foremost we needed a User class. We also know we would need a class for a Request, as well as a class for a Connection - it's important to keep these as individual models in order to separate concerns. We will be customizing our associations with these models using the Rails association methods of :class_name and :foreign_key. These are important because they allow us to customize our relationships in a way for this whole thing to work. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request Model&lt;/strong&gt;&lt;br&gt;
First let's build out our request model since that functionality will precede the connection model. This model is relatively simple and will look 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 Request &amp;lt; ApplicationRecord
  belongs_to :requestor, class_name: :User
  belongs_to :receiver, class_name: :User
end

create_table "requests", force: :cascade do |t|
    t.integer "requestor_id"
    t.integer "receiver_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically, we are telling Rails that the Request class belongs to TWO users - one is the requestor and one is the receiver of the request. This is why in our migration we specify their ids as we would with any belongs_to relationship. The only difference is that the User classes that this request belongs to are ALIASED to specify who the requestor is and receiver (as opposed to saying belongs_to :user - this would only allow us to have the request belong to a singular user with no alias). &lt;/p&gt;

&lt;p&gt;Now, in our User model we can specify this Request association. We essentially want to tell Rails that a User has many Requests, but with the caveat that this User is labelled as a Receiver or a Requestor. Similar to before, we will add alias names here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; has_many :connection_requests_as_requestor,
    foreign_key: :requestor_id,
    class_name: :Request

  has_many :connection_requests_as_receiver, 
    foreign_key: :receiver_id, 
    class_name: :Request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like before, we are specifying two has_many relationships where the User has many Requests as a Receiver, and has many Requests as a Requestor. We need to tell Rails what foreign key to associate this User with in the Request instance, which is why we specify &lt;code&gt;foreign_key&lt;/code&gt; in each of these associations. We could then call something like &lt;code&gt;user.connection_requests_as_requestor&lt;/code&gt; which would return to us a list of requests where the requestor is the user. That request would also contain the id of whoever the receiver was.&lt;/p&gt;

&lt;p&gt;We could then write two instance methods on the User class to gather incoming connection requests or pending (outgoing) connection requests. These would look something 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;  def incoming_pending_requests
    User.where(id: self.connection_requests_as_receiver.map{|request|request.requestor_id})
  end

  def outgoing_pending_requests
    User.where(id: self.connection_requests_as_receiver.map{|request|request.receiver_id})
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The incoming_pending_requests methods will return a list of Users who have requested to connect with the current user. The outgoing_pending_requests method will return a list of users that the current user has requested to connect with. You can imagine what a method to request a connection would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def request_connection(other_user_id)
  Request.create(requestor_id: self.id, receiver_id: other_user_id)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Connections&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we have our requests figured out. Let's move on to the connections model. This model functions very similarly to the Request model in that we will be using Alias names and foreign keys to allow the Connection instance to belong_to two distinct users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Connection &amp;lt; ApplicationRecord
  belongs_to :user_a, class_name: :User
  belongs_to :user_b, class_name: :User
end

create_table "connections", force: :cascade do |t|
  t.integer "user_a_id"
  t.integer "user_b_id"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
end

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

&lt;/div&gt;



&lt;p&gt;Almost identical to the Request class, out Connection model holds the foreign key to two separate Users (user_a and user_b) that it belongs to. That way, in our User class we can specify:&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
...
  has_many :a_users, foreign_key: :user_a_id, class_name: :Connection
  has_many :b_users, foreign_key: :user_b_id, class_name: :Connection

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

&lt;/div&gt;



&lt;p&gt;This means that a User has many connected Users where the user is user a, and there are many connected Users where the user is user b. Calling either of these association on the user will return an Active Record association containing a list of Connections where the current user is either a or b. So we should now write a method to accept an incoming request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def accept_incoming_connection(requesting_user_id)
    request = Request.find_by(requestor_id: requesting_user_id, receiver_id: self.id)
    requested_user = User.find(requesting_user_id)
    if request
      Connection.find_or_create_by(user_a_id: self.id, user_b_id: requesting_user_id)
      request.destroy
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically we are finding a request based on whoever has requested to connect with this current user. If there is a request, we then create a connection between the two users and destroy the request. It's that simple! Then to get a list of a user's connected users we write the method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; def connected_users
    connections = Connection.where("user_a_id = ? OR user_b_id = ?", self.id, self.id)
    User.where(id: connections.map{|c| c.user_a_id != self.id ? c.user_a_id : c.user_b_id})
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are getting a list of connections where the user_a_id or user_b_id is the current user. We then get an AR association of users who were included in these connections and who are not the current user. &lt;/p&gt;

&lt;p&gt;And that's all! We have successfully implemented a Connected Users relationship similar to something like LinkedIn. I hope you've enjoyed this article and feel free to leave comments or questions. &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>database</category>
      <category>associations</category>
    </item>
    <item>
      <title>Coding a React Carousel From Scratch</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Fri, 28 May 2021 03:10:11 +0000</pubDate>
      <link>https://dev.to/nicklevenson/coding-a-react-carousel-from-scratch-1f54</link>
      <guid>https://dev.to/nicklevenson/coding-a-react-carousel-from-scratch-1f54</guid>
      <description>&lt;p&gt;I have recently been working on an app for musicians to connect and be matched up with based on similar preferences. I wanted the UX/UI to be something like a tinder swiper where you can scroll through different profile cards. In the past I have used libraries like Bootstrap to achieve the carousel-like presentation, however, I wanted to challenge myself to build that out myself with vanilla JS within my React app. &lt;/p&gt;

&lt;p&gt;My first thoughts were to use CSS animation with toggled classes to move the cards in and out of the screen, however, I quickly found this method ineffective. I soon knew I would have to use JS to solve this problem. So allow me to walk you through my process. &lt;/p&gt;

&lt;p&gt;To start, I needed to have an array of data - recommended musicians to swipe through.This was relatively easy given I had stored those recommendations in my Redux state. Note, you don’t need Redux for this, I am just using it because I have redux implemented for the larger context of my application. All you really need is an array to map over.&lt;/p&gt;

&lt;p&gt;For Redux, all I had to do was map my state to props in the recommended users component like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mapStateToProps = (state) =&amp;gt; {
  return {
    currentUser: state.currentUser.currentUser,
    recommendedUsers: state.currentUser.recommendedUsers,
  };
};

const mapDispatchToProps = (dispatch) =&amp;gt; {
  return {
    fetchUserRecs: () =&amp;gt; dispatch(fetchUserRecs()),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(RecommendedUsers);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I mapped my the fetch recommended users dispatch function to props as well so when this component mounted in the application, it would fetch this data. &lt;/p&gt;

&lt;p&gt;Now was the time where I had to figure out how to actually implement the carousel-like behavior. After some experimentation, I decided that I would make the container for all the recommended user profiles to be a div that had an overflow hidden property, with a nowrap white-space property. This meant that the div could not break its line and would continue horizontally. I could then manipulate the scrollLeft margin of the container with JS to shift what is in view based on what card is shown. This is what the CSS looked like for the cards-container div, as well as the card class itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.cards-container {
    height: 100%;
    overflow: hidden;
    white-space: nowrap;
  }

 .card {
    display: inline-block;
    width: 100%;
    height: 100%;
    padding: 1rem;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next I had to define some state variables locally in the component itself. I needed to figure out what the index in the array of recommended users of the active card was, so that would be a variable. And then I need a variable to store the current scroll margin to implement. So my component state looked 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;state = {
    activeIndex: 0,
    margin: 0,
 };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My render function looked something 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; const shownUserId = this.props?.recommendedUsers[this.state.activeIndex]?.id || null;
      return (
        &amp;lt;div className="recommended-users"&amp;gt;
          &amp;lt;div className="cards-container"&amp;gt;
            {this.props?.recommendedUsers?.map((u, index) =&amp;gt; (
              &amp;lt;div&amp;gt;
                &amp;lt;PreviewUserCard
                  user={u}
                  currentUser={this.props.currentUser}
                  key={u.id}
                  cardChange={this.cardChange}
                  shownUserId={shownUserId}
                /&amp;gt;
              &amp;lt;/div&amp;gt;
            ))}
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      );

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

&lt;/div&gt;



&lt;p&gt;Basically I was mapping a component called PreviewUserCard that rendered all a user's information for each user in the recommended array. I passed in a callback function called cardChange that could be executed within the PreviewUserCard component. In the PreviewUserCard there is a button for the user to click that triggers this callback. This function is what would control the scrollLeft margin and change the active index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  cardChange = (e) =&amp;gt; {
    if (this.state.activeIndex === this.props.recommendedUsers.length - 1) {
      this.setState({ activeIndex: 0 });
      this.setState({ margin: 0 });
    } else {
      this.setState((state) =&amp;gt; ({
        activeIndex: state.activeIndex + 1,
        margin: state.margin + window.innerWidth
      }));

    }
  };

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

&lt;/div&gt;



&lt;p&gt;Basically, this function first checks if the current activeIndex is at the end of the recommended users array, and if it is, resets the active index to the first card - 0, as well as sets the margin to 0 as well. Otherwise, it will increment the activeIndex by 1 to the next user in the array and set the margin to the window width in addition to the previous margin. This is because a card is the width of the window and by increasing the scrollLeft margin by 100% we are essentially displaying the next card in the div. &lt;/p&gt;

&lt;p&gt;The last part of this puzzle is the incrementally set the scrollLeft value. If we changed it all at once, there would be no carousel effect at all. So I decided to write a function that would be executed whenever the component updated (it will execute whenever the cardChange function is called). This important function is called setMargin, which essentially increments the current scrollLeft value in smaller chunks to give it a nice flow and feeling of swiping. It looks 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;  setMargin = () =&amp;gt; {
    const container = document.querySelector(".cards-container");
    let interval = setInterval(() =&amp;gt; {
      let i = container.scrollLeft;
      if (i &amp;lt; this.state.margin) {
        container.scrollLeft = i + window.innerWidth / 100;
        if (container.scrollLeft &amp;gt;= this.state.margin) {
          clearInterval(interval);
        }
      } else {
        container.scrollLeft = i - window.innerWidth / 50;
        if (container.scrollLeft &amp;lt;= this.state.margin) {
          clearInterval(interval);
        }
      }
    }, 1);
  };

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

&lt;/div&gt;



&lt;p&gt;First we get the cards container element and set that to a variable. Then, we set an interval which takes the current value of that container scrollLeft margin. It then says, while this current scroll value is less than the component state's margin value (our target value), increment in small amounts the current scrollLeft value until we hit out target scrollLeft value and then clear the interval. If the current scroll value of the container is MORE than our target value, then that means we have reached the end of our array and have reset to 0. We then do a similar thing of changing the current scroll value until we hit our target, however this time we are decrementing down (and doing it faster for a nice effect). &lt;/p&gt;

&lt;p&gt;And that's it! If you've successfully followed along, you now know how to implement this yourself. There probably is a better way to do this, and I would love to implement touch events and smoothing incrementation (now it is all linear so it could be more natural), but for now I am proud to have came up with this method. It would probably be faster to just use a library like React-Carousel, or Bootstrap's Carousel, but this was a fun and enjoyable challenge. Feel free to comment any other solutions you may have to creating a carousel-like presentation. Thanks for reading!&lt;/p&gt;

</description>
      <category>react</category>
      <category>carousel</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Sanitizing SQL in Rails/ActiveRecord</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Fri, 21 May 2021 18:26:35 +0000</pubDate>
      <link>https://dev.to/nicklevenson/sanitizing-sql-in-rails-activerecord-2p3p</link>
      <guid>https://dev.to/nicklevenson/sanitizing-sql-in-rails-activerecord-2p3p</guid>
      <description>&lt;p&gt;ActiveRecord methods are great for easily querying your database. However, at some point you'll probably have to implement custom sql into your application if the traditional ActiveRecord methods won't get you what you need. When writing custom SQL in Rails, it is important to sanitize it, making sure there's no chance for an injection attack. Sometimes, however, you will have to interpolate Ruby variables into your SQL queries, but regular interpolation can be insecure. So what's the solution? &lt;/p&gt;

&lt;p&gt;I have recently been working on an application with a Rails backend, that essentially matches musicians with each other based on similar interests, locational range, etc. When I was working on my Rails application recently, I had to write a long custom SQL statement. I wanted to make a method that could find users based on range, similar tags, and any filters like genres or instruments (in relation to the current user). &lt;/p&gt;

&lt;p&gt;The query needed to be dynamic - the method containing the query took in arguments and those arguments would affect what the query would be looking for. Here is some pseudo code of the method I wanted to create.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def similarly_tagged_users(range: nil, instruments: nil, genres: nil)
 #NO IDS - get a list of ids of users who the current user is 
 already connected with, has rejected, or is the current user 
 themselves.

 #FILTERED RANGE IDS - see if the user applied a mile radius 
 to apply to the query
 #get a list of ids of users who are in range of the current 
 user

 #OTHER IDS TO FILTER BY - see if the user applied filters 
 (list of instruments and genres)
  #get a list of ids of users who play these instruments or 
  identify with these genres

 #these will all be arrays of ids above. 

 #write a query to sort users by tags that match the current 
 user so users with the most similar tags appear first, as 
 well as not include any of the NO IDS, filter by RANGE IDS, 
 and OTHER IDS TO FILTER BY. Limit results to only 50 users. 

end

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

&lt;/div&gt;



&lt;p&gt;Ok so we have our pseudo code. We know that we will have an array of ids of users to exclude in the query, an array of users that fit the range parameters, as well as an array of ids of users with instruments and genres that match the query. Here's where the sanitization comes in.&lt;/p&gt;

&lt;p&gt;ActiveRecord has a sanitization method called &lt;a href="https://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html" rel="noopener noreferrer"&gt;sanitize_sql_array&lt;/a&gt;, that lets you pass an array into a SQL statement. It looks like: &lt;code&gt;sanitize_sql_array(["name=? and group_id=?", "foo'bar", 4])&lt;/code&gt;. You pass an array into the method where the first index is the SQL query you want to write with the question mark placeholder, and the following indexes are variables you can pass in. With this method, any sql injections will be escaped, so you can safely pass variables to your query. &lt;/p&gt;

&lt;p&gt;So for example, my users in range looks 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;range_query = range ? conn.sanitize_sql_array(["u.id IN(?)", self.users_in_range(all_users, range)]) : "true"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am checking if there is range in the parameters of the method, and if there is, returning the sanitized sql that has executed the method that returns an array of user ids that are in range of a given radius. So that variable, range_query, can be accessed and put into the custom SQL query I would write later. One thing I should note is that you have to establish a connection with the ActiveRecord base to execute these methods. You may notice before the method is 'conn'. Before I use these methods I write: &lt;code&gt;conn = ActiveRecord::Base&lt;/code&gt; so I can use conn as the base for the sanitization methods. &lt;/p&gt;

&lt;p&gt;In the end, my sql query looked 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;sql2 = &amp;lt;&amp;lt;~SQL
      SELECT u.*, COALESCE(matching_tag_counts.n, 0) AS similarity_score
      FROM users AS u
        LEFT OUTER JOIN (
          SELECT user_id, COUNT(*) AS n
          FROM usertags
          WHERE #{conn.sanitize_sql_array(["tag_id IN(?)", self.tag_ids])}
          GROUP BY user_id
        ) AS matching_tag_counts ON u.id=matching_tag_counts.user_id
        WHERE #{conn.sanitize_sql_array(["u.id NOT IN(?)", no_ids])}
        AND #{range_query}
        AND #{genre_instrument_query}
        ORDER BY similarity_score DESC
        LIMIT 50
    SQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see how I interpolated variables that have already been sanitized (range_query and genre_instrument_query). I also interpolated the sanitize_sql_array method in a couple areas. So this is how you can safely interpolate in a custom SQL queries.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>activerecord</category>
      <category>ruby</category>
      <category>sql</category>
    </item>
    <item>
      <title>How to Speed Up Load Times In A Rails App - What I Wish I Knew Four Months Ago</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Thu, 13 May 2021 19:55:33 +0000</pubDate>
      <link>https://dev.to/nicklevenson/how-to-speed-up-load-times-in-a-rails-app-what-i-wish-i-knew-four-months-ago-28g0</link>
      <guid>https://dev.to/nicklevenson/how-to-speed-up-load-times-in-a-rails-app-what-i-wish-i-knew-four-months-ago-28g0</guid>
      <description>&lt;p&gt;Not too long ago I was introduced to Ruby on Rails through my time as a Flatiron student. To those familiar with the Ruby framework, Rails makes creating complex MVC web applications very simple. It wasn't long before I started developing fairly complicated apps with Rails. However, after gaining a fair amount of users on my Heroku hosted app &lt;a href="https://memix.herokuapp.com/" rel="noopener noreferrer"&gt;MeMix&lt;/a&gt;, I ran into some big problems. My application kept crashing. It hadn't been crashing before, and after some diagnostics with the &lt;a href="https://one.newrelic.com/" rel="noopener noreferrer"&gt;New Relic&lt;/a&gt; analytics tool, the problem became clear - slow database loading times. Heroku will automatically crash your app if your load time takes more than 30 seconds. I clearly had a big problem with my database queries, something that is referred to as N+1 queries. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Problem&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A big cog in the Rails machine is something called Active Record. Let's say we had two models that are associated with each other: (I actually made a &lt;a href="https://github.com/nicklevenson/includes-blog" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt; with this sample so you can easily try it yourself)&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; ActiveRecord::Base
  has_many :posts
end

class Post &amp;lt; ActiveRecord::Base
  belongs_to :user
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Active Record, a typical and easy way to access a list of a user's posts, and what I learned at bootcamp, would be to write &lt;code&gt;User.posts&lt;/code&gt;. But what if we want to iterate over a list of Users and then iterate over each user's posts? We could write something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User.all.each do |user|
  user.posts.each do |post|
    puts post.content
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will work just fine. However for each user we are querying the database for their posts. Which means our query complexity has become N+1. N being the number of users, since for each user we make a request to the database for its associated posts, and plus one query for getting all users. &lt;/p&gt;

&lt;p&gt;This is totally fine if you have a small database. However, once your database grows, and if you have complicated associations, it will start to slow down. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Solution&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://guides.rubyonrails.org/active_record_querying.html#eager-loading-multiple-associations" rel="noopener noreferrer"&gt;ActiveRecord has a method&lt;/a&gt; called includes. Basically it allows you to load a model's associations in a single query. So in our example before, you would write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User.includes(:posts).all.each do |user|
  user.posts.each do |post|
    post.content
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the difference between the queries when looking at the database output in the console:&lt;/p&gt;

&lt;p&gt;Bad Query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User.bad_query
  User Load (0.2ms)  SELECT "users".* FROM "users"
  Post Load (0.1ms)  SELECT "posts".* FROM "posts" WHERE "posts"."user_id" = ?  [["user_id", 1]]
hello
  Post Load (0.1ms)  SELECT "posts".* FROM "posts" WHERE "posts"."user_id" = ?  [["user_id", 2]]
hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good Query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User.good_query
  User Load (0.2ms)  SELECT "users".* FROM "users"
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (?, ?)  [[nil, 1], [nil, 2]]
hello
hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can you spot the extra db call in the bad query? This is just with two users, but its easy to imagine a complicated db structure causing major speed issues. The cool thing about includes is that you can chain on as many associations as you want - &lt;code&gt;User.includes(:posts, :followers, :likes).all&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Sometimes, however, using this handy active record method could slow down your app if the database query is very complicated (e.g. nested associations, many-to-many, etc). It can be hard to know when it is more efficient to use it. However, there is a gem called &lt;a href="https://github.com/flyerhzm/bullet" rel="noopener noreferrer"&gt;Bullet&lt;/a&gt; that is designed to help with this exact issue. It will tell you when your query chains are inefficient and what to do about it. &lt;/p&gt;

&lt;p&gt;After implementing this technique on my slow Rails app, the average load time went down from 10-15 seconds to 2-3 seconds. So if you're experiencing slow load times, please consider checking your query methods, and look for N+1 queries. I wish I knew this when I built my first Rails app.  &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>database</category>
      <category>activerecord</category>
    </item>
    <item>
      <title>Insight for an Incoming Flatiron School Student</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Thu, 25 Mar 2021 20:43:37 +0000</pubDate>
      <link>https://dev.to/nicklevenson/advice-to-an-incoming-flatiron-school-student-400a</link>
      <guid>https://dev.to/nicklevenson/advice-to-an-incoming-flatiron-school-student-400a</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
I am just finishing up my full time software engineering bootcamp through Flatiron School. When I decided to attend a software engineering bootcamp I had no idea what to expect. All I knew was that I loved the small amount of coding I had experimented with and I wanted to pursue a career doing it. I did a lot of research going into the program and I tried to prepare myself as well as I could, but at the end of the day, I was still taking a big leap of faith into a world I knew little about. So you've decided to pursue a bootcamp and you've chosen Flatiron as the school, here's what I can tell you about my experience. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Aside: One thing I can tell you upfront is that if you're just doing this for the money or any other reason besides a genuine love for code, you probably won't do well in this program.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 1&lt;/strong&gt;&lt;br&gt;
The first couple weeks of the program was busy and hectic. There were a lot of students to start out and we were all getting our bearings with the program and its format. This part of the program you will be learning Ruby. I would say that this is one the more important parts of the program. There is a lot of new information during this first phase. After all,  you're learning a completely new skill. My advice for this phase is to have prepared coming into the phase by taking Flatiron's free bootcamp prep course. Not only will you get a better sense of the feel of the program and if you like it, but you will have set yourself up to get ahead or keep up with the fast paced lessons in this first phase. It was easy to fall behind in this phase, which WILL affect the rest of your program. The best thing you can do for yourself in the program is to stay ahead of the curriculum so you have time to review, make awesome projects, and not fall behind if things get tough. At the end of each of the 5 phases of the program, you will complete a project - if you're ahead in the curriculum you will have more time to finish these projects. This is crucial because these projects are how you pass through each phase, and also what matters on your resume. At the end of this phase, I made a simple command line interface (CLI) application that showed users information about the solar system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2&lt;/strong&gt;&lt;br&gt;
Once you make it through the first phase of coding basics, that is a huge milestone. The next phase, Sinatra, will be confusing and exciting. Sinatra is an old framework for creating web applications with Ruby. They teach you this because it is a good way of understanding the concepts behind web development. It is, however, a bit head-achy and difficult to initially wrap you mind around. That being said, at the end of this section you will build your first web application which was extremely exciting for me. My project was a &lt;a href="http://recipe-freak.herokuapp.com" rel="noopener noreferrer"&gt;recipe sharing site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 3&lt;/strong&gt;&lt;br&gt;
Once you make it to the third phase, Ruby on Rails, you should start brainstorming project ideas immediately. Rails is a framework that makes you mad you spent time learning Sinatra. Rails makes web development feel much more accessible. However, this section is a long and tough one. Rails is built on convention, so there is a lot of syntax to wrap your mind around. Once you understand how to use it though, you can build very powerful applications quickly. That is why brainstorming an awesome project idea early is important. I never waisted valuable project time on brainstorming. I always brainstormed while I was learning the curriculum material, before project week came around. That way, I was able to have extra time building out my ideas. Rails will give you great tools for creating complicated projects - so think bigger! &lt;a href="https://memix.herokuapp.com/" rel="noopener noreferrer"&gt;My Rails project&lt;/a&gt; ended up being a social media site where users could curate and share artistic content, such as music, art, movies, etc..., vie a personalized mix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 4&lt;/strong&gt;&lt;br&gt;
Once I learned Rails, I felt like a pro developer. For a week. Then the JavaScript phase came around. Coming off a high of confidence after developing a cool Rails application, the JavaScript section felt like a step back. It felt like the first phase again where we were learning from level 0. However, towards the end of the phase, you start learning crucial and foundational skills in you web development toolkit. I had a great time building my JavaScript project which was a &lt;a href="https://nicklevenson.github.io/planegame/" rel="noopener noreferrer"&gt;paper airplane throwing game&lt;/a&gt;. This project requires you to separate out your frontend (JavaScript) and your backend (Rails) - A foreign concept that will become basic soon. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 5&lt;/strong&gt;&lt;br&gt;
After JavaScript you're in the final phase, React(a framework for JavaScript) + Redux. This phase is awesome. It is initially confusing (as always), but you get to learn modern frameworks for the frontend. These skills are crucial in being a full stack developer or a frontend developer. Nevertheless, by the end of this section you'll feel the most free in terms of creating a project. You will have learned backend development with Rails, and frontend development with React, Redux, and JavaScript - All the tools you need to make a modern web application. My final project ended up being a &lt;a href="https://map-mate-frontend.herokuapp.com/public-maps" rel="noopener noreferrer"&gt;map making site&lt;/a&gt; where users could share, collaborate, and add geolocational markers to their maps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
And now I am finished with the program, looking for work opportunities, and writing this article as a reflection and hopefully a helpful insight into the Flatiron experience. Towards the end of the program, you are matched with a career coach who helps you navigate your job search. Don't expect Flatiron or your career coach to get you a job - that is completely up to you, however, they will help you navigate the waters. Just remember that the more effort you put into the program, the more you will get out of it. The more time you spend each day on the curriculum, means more time working on your projects, and exploring topics outside of the course. Good luck, happy coding, and feel free to ask questions in the comments!&lt;/p&gt;

</description>
      <category>flatiron</category>
      <category>bootcamp</category>
      <category>newbie</category>
    </item>
    <item>
      <title>Utilizing Mapbox to Build a Map Making Site with React, Redux and Rails</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Sun, 21 Mar 2021 20:10:25 +0000</pubDate>
      <link>https://dev.to/nicklevenson/utilizing-mapbox-to-build-a-map-making-site-with-react-redux-and-rails-1im1</link>
      <guid>https://dev.to/nicklevenson/utilizing-mapbox-to-build-a-map-making-site-with-react-redux-and-rails-1im1</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
I built a website where users could easily create their own maps for whatever purpose they see fit. They are able to add markers to any place in the world, share their maps, and collaborate with other users on maps. This article will cover some of the details of building this site. You can visit and use the site &lt;a href="https://map-mate-frontend.herokuapp.com/public-maps" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Or look at a &lt;a href="https://vimeo.com/526993359" rel="noopener noreferrer"&gt;Video Demo&lt;/a&gt;. You can also view the front-end code &lt;a href="https://github.com/nicklevenson/maps-frontend" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Mapbox&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.mapbox.com/" rel="noopener noreferrer"&gt;Mapbox&lt;/a&gt; is an easy to use, powerful map tool for developers. They have a very generous free tier of api calls so I never had to worry about going over their limit, and I found it a little easier to use than google maps api. To start, you just have to go to their website, create an account, and get an api key. &lt;/p&gt;

&lt;p&gt;I was using React for this project, so loading in the map was a little different than doing it with vanilla JS/HTML. First you need to install the mapbox api with npm or yarn. I imported the following to get started with mapbox on my map component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mapboxgl from 'mapbox-gl'
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mapbox needs a div with an id to attach its map to. Therefore, I had to render the map container before I actually rendered the map. That is why I had the renderMap() function in componentDidMount, since it needed the div to be on the html.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Map extends React.Component {

  componentDidMount() {
    this.renderMap()
  }

  render(){
      return(
        &amp;lt;&amp;gt;
          &amp;lt;div className="map-container"&amp;gt;
            &amp;lt;div id="map"&amp;gt;&amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/&amp;gt;
      )
  }

  renderMap() {
    mapboxgl.accessToken = process.env.REACT_APP_API_KEY;
    const map = new mapboxgl.Map({
      container: 'map', // container ID
      style: 'mapbox://styles/nicklevenson/ckm82ay4haed317r1gmlt32as', // style URL
      center: [-77.0353, 38.8895], // starting position [lng, lat]
      zoom: 1 // starting zoom
    });
    map.addControl(
      new MapboxGeocoder({
      accessToken: process.env.REACT_APP_API_KEY,
      mapboxgl: mapboxgl
      })
    );
    this.setState({map: map})
    document.querySelectorAll(".mapboxgl-ctrl-geocoder--input")[0].placeholder = "Search for Places"
  } 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the code above, we are rendering the mapbox map, as well as their Geocoder api which allows you to search for places and addressed on the map. You can see where I put my API key to have access to mapbox using the dotenv package for development. Once you have that, you can add a lot of other features that mapbox has to offer. For my project I wanted to be able to add markers to the map.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;renderMarkers(){
    this.props.markers.forEach(marker =&amp;gt; RenderMarker({
      marker: marker, map: this.state.map, 
      handleMarkerSelect: this.props.handleMarkerSelect, 
      destroyMarker: this.props.destroyMarker, 
      currentUser: this.props.currentUser,
      selectedMap: this.props.selectedMap,
      handleRemoveMarker: this.handleRemoveMarker,
      handleMarkerAdd: this.handleMarkerAdd
    }))
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start, I wanted to render markers for all the markers coming in from the database (this.props.markers). The object being passed to the RenderMarker() function is simply a few functions that assisted in handling the redux state and database calls. It also gave the marker information about itself - like title, user, the currentuser, etc...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const coords = [props.marker.lng, props.marker.lat];
 const el = document.createElement('div');
    el.className = 'marker';
    el.style.backgroundImage = `url(${props.marker.user.image})`
      const marker = new mapboxgl.Marker(el)
      .setLngLat(coords)
        .setPopup(new mapboxgl.Popup({ offset: 25 }) // add popups
        .setHTML(
          `&amp;lt;h3&amp;gt;${props.marker.title}&amp;lt;/h3&amp;gt;
          &amp;lt;i&amp;gt;By: ${props.marker.user.username}&amp;lt;/i&amp;gt;
          &amp;lt;br&amp;gt;
          &amp;lt;i&amp;gt;Coordinates: [${coords}]&amp;lt;/i&amp;gt;
          &amp;lt;textarea readonly&amp;gt;${props.marker.info}&amp;lt;/textarea&amp;gt;
          ${props.marker.image ? `&amp;lt;image src=${props.marker.image} alt="marker image" class="marker-image"&amp;gt;&amp;lt;/image&amp;gt; `: `&amp;lt;br&amp;gt;`}
          `
        ))
        .addTo(props.map);

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

&lt;/div&gt;



&lt;p&gt;In the renderMarker() function, the code above is what actually renders a marker on the map. You have to create a div for the marker on the html. I made the marker to be the user's profile image. Then, I set a popup for the marker. This is mapbox's easy way to make a marker clickable to show more information. All you do is create the popup, then use mapbox's built in function to set the innerHTML of the popup. In this case, I would add the title, username, description, and image. Lastly, you had to append the marker to the map with the .addTo function. The marker would then appear on the map! Once data was flowing from my database api to the redux state, it was easy to render these markers on the maps. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rails Api&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I won't go too deep into this section, but I wanted to show you the schema for the application to get a better sense of how data was being stored and fetched. &lt;/p&gt;

&lt;p&gt;I wanted users to have many maps, and for maps to have many users. This way, people could add collaborators to their maps. Therefore, I needed a joins table (user-maps) to create that many-to-many relationship. I wanted users to have many markers, and for markers to belong to a user. Maps should have many markers and markers should have many maps. This many-to-many relationship (marker_maps) allowed me to give users the ability to add other people's markers to their own maps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  create_table "maps", force: :cascade do |t|
    t.string "title"
    t.string "description"
    t.boolean "public", default: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "marker_maps", force: :cascade do |t|
    t.integer "marker_id"
    t.integer "map_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "markers", force: :cascade do |t|
    t.integer "user_id"
    t.string "title"
    t.string "info"
    t.string "image"
    t.decimal "lng", precision: 10, scale: 6
    t.decimal "lat", precision: 10, scale: 6
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "user_maps", force: :cascade do |t|
    t.integer "user_id"
    t.integer "map_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "username"
    t.string "email"
    t.string "uid"
    t.string "provider"
    t.string "image", default: "https://icon-library.net//images/no-user-image-icon/no-user-image-icon-27.jpg"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

end

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;React + Redux&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wanted to use Redux for state management since this app was going to be fairly complicated when it came to that. It would be nice to have a store for my state that I could access from any component, rather than pass a bunch of props down from components. I also knew I would be making many fetch requests to the backend so I used the middleware Thunk to make those requests work well with Redux. It basically allowed me to make async calls and update the Redux store when it got data, so the app didn't have to constantly wait for database to respond. I set this up in my index.js file like so:&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 ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {BrowserRouter as Router} from 'react-router-dom'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import rootReducer from './reducers/rootReducer.js'
import {composeWithDevTools} from 'redux-devtools-extension'
import thunk from 'redux-thunk'
import 'semantic-ui-css/semantic.min.css'
import 'mapbox-gl/dist/mapbox-gl.css'
const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)))
ReactDOM.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;Provider store={store}&amp;gt;
      &amp;lt;Router&amp;gt;
        &amp;lt;App /&amp;gt;
      &amp;lt;/Router&amp;gt;
    &amp;lt;/Provider&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;,
  document.getElementById('root')
);

reportWebVitals();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rootReducer is a function that combines my reducers into one, and that is being connected to the redux store with the store variable. That variable gets passed to the provider component which connects my app with the redux store as well as dispatch actions. &lt;/p&gt;

&lt;p&gt;Here's an example of an action in my application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const addMaps = (maps) =&amp;gt; ({type: "ADD_MAPS", payload: maps})

export const fetchMaps = () =&amp;gt; {
  return (dispatch) =&amp;gt; {
    fetch(`${process.env.REACT_APP_BACKEND_URL}/maps`)
    .then(res =&amp;gt; res.json())
    .then(maps =&amp;gt; {
       dispatch(addMaps(maps))

    })
    .catch(function(error) {
      alert("Errors getting maps.")
    })
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically, I am fetching maps from my database and then dispatching them to the store so redux has access to all the maps. This way, I can connect any component to my redux store and access those maps from the database. My application had many more actions like this, including actions to create, edit, and delete maps. You could see how this could get really complicated using React only, but Redux makes it so much easier to contain these complicated actions and data relationships into one place. It allowed me to connect a component to the store and dispatch actions. For example, once I mounted my map component, I could then make the call to fetch its markers so it happens in the background and the user isn't left with a boring loading sign.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This application was complicated to build and I only scratched the surface in this article. This project made me appreciate the functionality that Redux and Thunk brings to a React app. It also was really cool to use the Mapbox api - there are so many different routes to take with it. I hope this article shed some light on how to use Mapbox, as well as show why Redux is useful. Please ask questions in the comments and I hope you check out the project!&lt;/p&gt;

</description>
      <category>mapbox</category>
      <category>rails</category>
      <category>react</category>
      <category>redux</category>
    </item>
    <item>
      <title>Game Building with JavaScript</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Thu, 18 Feb 2021 23:13:14 +0000</pubDate>
      <link>https://dev.to/nicklevenson/game-building-with-javascript-4j7a</link>
      <guid>https://dev.to/nicklevenson/game-building-with-javascript-4j7a</guid>
      <description>&lt;p&gt;For my latest coding project I decided to build a simple game using vanilla JavaScript, CSS, HTML, and a Ruby on Rails backend to keep track of user data. The game would be straight forward, throw a paper plane at a target and score points. Some topics I'll cover in this article HTML Canvas and JS, Rails as an API, and fetching data with JS. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://nicklevenson.github.io/planegame/" rel="noopener noreferrer"&gt;Play the game&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/nicklevenson/planegame" rel="noopener noreferrer"&gt;View the code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://vimeo.com/513994621" rel="noopener noreferrer"&gt;Video demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Canvas&lt;/strong&gt;&lt;br&gt;
I started the project by developing the game functionality. I wanted to have a game consist of 10 rounds, each throwing the plane at a target. I used the HTML element Canvas as my animation medium, and manipulated all the data with JS. &lt;/p&gt;

&lt;p&gt;First thing is first, I placed a canvas object in my HTML doc. When a round starts, we will access this object and go from there. Below is the code where we get elements from our HTML, prepare our canvas, and the objects we will animate. Be sure to follow along with the comments. There was a lot to this part of the project, so I can't cover it all in this article, but I encourage you to study the github code if you're interested and want to dive deeper.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//lets grab these elements. We need to grab the slide for the power, and the canvas itself.

      const slideContainer = document.getElementById("speedSlider")
      const slide = document.getElementById("slide")
      let canvas = document.getElementById("myCanvas");

//sizing

//This is where we set the canvas size. 
//I wanted to base it on the current screen's height and width so its responsive.
//For objects within the canvas, we will set heights and widths relative to the canvas. 

      canvas.height = (screen.height * .5)
      canvas.width = canvas.height * .75 - 100
      leaderboardContainer.style.height = canvas.height + "px"
      gameStats.style.width = canvas.width + "px"

//plane sizing
      let planeW = canvas.height * .05;
      let planeH = planeW * 1.25;
//target sizing
      let targetW = canvas.height * .125;
      let targetH = targetW;
//size of power slide
      slideContainer.style.height = (canvas.height) + "px"
      let slideH = slideContainer.offsetHeight
//size of the wind arrow object
      let windW = 25
      let windH = 50
//Here we set ctx to the inner context of the Canvas. 
//We will use ctx from here to control actions within the canvas. 
//Transform allows us to flip the canvas Y axis to be more intuitive from its original orientation

      let ctx = canvas.getContext("2d");
      ctx.transform(1, 0, 0, -1, 0, canvas.height)

//lastly, we will set initial coordinates (x,y) for the plane. The plane will always follow these coordinates. 
      let x = canvas.width/2;
      let y = 30;
//dx and dy are what we will use to give the plane a trajectory or (velocity). They will start at 0 since we aren't moving the plane yet.
      let dx = 0;
      let dy = 0;
//angle will be the initial angle of the plane with a direction set to 'right' this will be used when we animate the angle of the plane
      let angle = 0
      let direction = "right"

//calibration
   //I won't go into this much since it is fairly complicated, but we are essentially setting the wind power, and the gravity.
      //negative wind is a n || e. positive wind is s || w 
      let windY = getWind().y
      let windX = getWind().x
      // let windY = 0
      // let windX = 0
      let windDirection = getWindDirection()
      let windAngle = getWindAngle()
      // let windPower = (((Math.abs(windY) * Math.abs(windX))+1)* 10).toPrecision(3)
      let windPower = ((Math.sqrt((Math.abs((windX*100)**2)) + (Math.abs((windY*100)**2))))).toPrecision(3)

      let power = 0

//we set the gravity to the height of the canvas. This will limit out plane's flight.
      let gravity = canvas.height

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

&lt;/div&gt;



&lt;p&gt;Phew, that was a lot of sizing. Now we have the sizes of everything set relative to the canvas - which is set relative to the viewport. Now we need to start drawing and implementing some logic. First the plane needs to iterate through different angles for the user to then pick an angle for the flight.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//lets start a round
 function startRound() {
//control is the button that users press to control everything
        control.innerText = "Angle..."
//lets call the drawing function that angles the plane. We use setInterval() to create animation frames. 
        anglage = setInterval(moveAnglePlane, 50);
//When the user clicks the angle, we clear the angle animation and trigger the power slider animation.
        control.addEventListener('click', function space(e){
            control.innerText = "Power..."
            clearInterval(anglage)
            sliderLoop()
            startSlide()
            control.removeEventListener("click", space);
        })
      }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, let's jump to the part where we are actually animating the angle choice on the canvas. This is the function that we just set an interval on. Animating things in Canvas requires us to draw and redraw everything in the canvas every single frame, kind of like a spool of film or stop motion animation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; function rotatePlane() {
//we draw the target, wind, and wind power text on the canvas every screen since each animation frame in the canvas is completely cleared and redrawn.
      drawTarget()
      drawWind()
      drawWindPower()
//we use translate to orient the plane's anchor to its x and y coordinates from before
      ctx.translate(x, y);
//we use rotate to angle the plane to its set angle variable from before
      ctx.rotate(angle);

 //drawImage is a canvas function to draw on an image asset (the plane in this case)
      ctx.drawImage(img,-(planeW/2),0,planeW,planeH)
//the logic below allows the plane to change its angle direction if it hits a certain angle. This provides us with our cycling of angles in the game for the user to choose from.
      if (angle &amp;gt;= 1.5) {
        direction = "left"
      }   
      if (angle &amp;lt;= -1.5) {
        direction = "right"
      }
//our anglePlane function essentially executes every frame, adding or subtracting a tiny amount from the angle based on the direction it is currently in. 
    angle = anglePlane(angle, direction)
    }

//this is the actual function we called with our setInterval in the startRound function. This just clears the canvas, saves it, and draws the plane's rotation (with the rotatePlane()). 
    function moveAnglePlane() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.save();
      rotatePlane()
      ctx.restore();
    }
    function anglePlane(angle, direction) {
      if (direction === "right") {
        return angle + 1/10
      }
      if (direction === "left") {
        return angle - 1/10
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, the last set of functions allows the plane angle to cycle through and allow it to be chosen by the user on a click. Once it is clicked, we start the power slider - we call the sliderLoop() function. This function isn't shown here, but it essentially animates the power bar for the user to choose power. startSlide() is also called after we chose the angle. This function just sets the control bar to listen for a click and execute some other functions - most importantly, moving the plane forward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function startSlide() {
        control.addEventListener('click', function space(e){
            control.innerText = "Throw!"
            control.style.backgroundColor = "grey"
//stop the power bar loop
            clearTimeout(doSlide)
//play a sound
            woosh.play()
//call the movePlane() function we will see below.
            movePlane() 
//add to the throw count in the document
            throwCount ++
            throwCountTitle.innerText = `(${throwCount} throws and counting!)`
//lastly removing the event listener from being triggered again.
            control.removeEventListener("click", space);
        })
      }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will get into the actual animation of moving the plane forward. This required some math that I hadn't used since high school. Namely pythagorean theorem...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function movePlane() {
//getTrajectory gets an X and Y target value based on the angle of the plane and the power that the user chose. See it at the bottom of this block. Thats the pythagorean happening.
      let XY = getTrajectory()
//with out XY object we now have to check the angle of the plane, check if its going left or right of the center of the canvas. 
//We then set our dx and dy variables to these values added/subtracted with our current x,y location.
      if (angle &amp;gt;= 0) {
        dx = Math.round(x - XY.x)
        dy = Math.round(y + XY.y)

      }else{
        dx = Math.round(x + XY.x)
        dy = Math.round(y + XY.y)
      }
      //now we set an animation function interval to loop.
      anglage = setInterval(forwardPlane, 1)
    }

    function forwardPlane() {
// lets clear the canvas
      ctx.clearRect(0, 0, canvas.width, canvas.height);
//now we draw our target, wind, and wind power text every frame
      drawTarget()
      drawWind()
      drawWindPower()
      ctx.save();
//angle the plane to its angle the user had set
      ctx.translate(x, y);
      ctx.rotate(angle);
//here we draw our plane image
      ctx.drawImage(img,-(planeW/2),0,planeW,planeH)
//this logic checks if we are going left or right of the middle of the canvas (vertically).
//We then set the x,y based on the dx and dy values, incrementing it every time this animation loop happens.
      if (angle &amp;gt;= 0) {
          x -= (((canvas.width/2) - dx)/canvas.height) 
          y += (( dy-30)/canvas.height)
      }else{
          x += ((dx - (canvas.width/2))/canvas.height)
          y += (( dy-30)/canvas.height)
      } 
      ctx.restore();

//this is how we affect the plane's trajectory based on the wind
//the wind power have powers for both the X and Y axis
//we decrement the plane's destination coordinates every animation frame based on the wind powers
      dy -= windY
      dx -= windX
//we wait until the gravity variable (set in the start) runs out. 
//Once it does, we stop moving the plane and check for a collision with the target.
      if (gravity &amp;lt;= 0) {
        clearInterval(anglage)
        ctx.restore()
        slide.style.height = 0
        addScore(collision())
      }
//if gravity hasn't run out, we decrement it one each animation frame until it does.
      gravity -= 1


    }

    function getXY(sideC, angle){
      const sideA = sideC * Math.sin(angle)
      const sideB = Math.sqrt((sideC**2) - (sideA**2))
      return {sideA, sideB}
    }

    function getTrajectory() {
//setting the power of the plane to the slide height that the user set on when they clicked. 
      power = slide.clientHeight;
      let XY = getXY(power, angle)
      let moveY = XY.sideB
      let moveX = Math.abs(XY.sideA)
      return {y: moveY, x: moveX}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are some pieces missing here, but we have essentially got the plane angled and moving! After a round's functionality was working, I wrote some game logic. There were 10 rounds in a game, and each round would tally to your game's score. At the end of each game, we would send the score to the database. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rails Backend&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The rails backend would be very simple. I wanted there to be a user who has many scores, and scores which belong to users. To start the api, I used this command to easily set everything up quick: &lt;code&gt;rails new filename --api --database postgresql&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Once I set up my database, models, and routes, I just had to render the json that I wanted to access from the frontend. My controllers looked something 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;Scores:
 def index
    scores = Score.high_scores
    all = Score.all.count
    render json: {scores: scores, all: all}
  end
  def create
    Score.create(score_params)
    render json: {message: "success"}
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The class method high_scores just takes in the top 25 scores for the game. When sending in new scores from the front end, I would include the current user id and then the score value.&lt;/p&gt;

&lt;p&gt;My Users controller was equally simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def create
    user = User.find_or_create_by(user_params)
    scores = user.scores.collect{|s|s.score}.reverse
    if user.save
      render json: {username: user.username, id: user.id, scores: scores}
    else
      render json: {error: {message: "Username cannot be blank"}}, status: 400
    end
  end

  def show
    user = User.find(params[:id])
    scores = user.scores.collect{|s|s.score}.reverse
    render json: {username: user.username, id: user.id, scores: scores}
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I basically wanted to create or find a user before a game is played, and return their scores if they have played before. &lt;/p&gt;

&lt;p&gt;And just like that, it was all set up. I was easily able to upload the api to Heroku given I was already using a postgresql db. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JS Fetch&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once I had the backend up on a server, I could make fetch requests from the frontend in order to create users, display and submit their scores. Here is an example of how I created users from the frontend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//called when a user clicks a button in the frontend
function submitUser() {
//play sound effect
  woosh.play()
//remove the event listener to avoid multiple clicks
  newUserSubmit.removeEventListener('click', submitUser)
//loading card incase the server takes a second
  let loading = new loadCard(newUserContainer)

//make a config object for the fetch request. This will be a post request sending the value that the user submitted.
  let configObj = {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Accept": "application/json"
    },
    body: JSON.stringify({
      username: newUserInput.value
    })
  }
//send the fetch request
  fetch("https://planegame-api.herokuapp.com/users", configObj)
  .then(resp =&amp;gt; resp.json())
//get the json response to JSON. Should be the new or existing user along with scores if they have played already
  .then(function(json){
    if (json.error === undefined){
//if there are no errors create a new User instance for the session and hide the loading card
      setUser(json)
      loading.hideCard()
    }else{
      alert(json.error.message)
      loading.hideCard()
    }
    newUserSubmit.addEventListener('click', submitUser)
    })
  .catch(function(error){ 
//if there are errors, lets do it again!
    alert("Please check your internet connection.")
    newUserSubmit.addEventListener('click', submitUser)
    loading.hideCard()
  })

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

&lt;/div&gt;



&lt;p&gt;And there you have it. A simple post request that creates or finds a user in the api, and then returns that user's information for the JS frontend to work with throughout the session.&lt;/p&gt;

&lt;p&gt;There was a lot to cover in this article, and I definitely did not get to it all. I hope some of the information in the article was helpful. As always, I welcome feedback on my code and will take any questions in the comments.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>rails</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Building a Multimedia Content Sharing Website With Rails</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Sun, 24 Jan 2021 01:00:39 +0000</pubDate>
      <link>https://dev.to/nicklevenson/building-a-multimedia-content-sharing-website-with-rails-1gce</link>
      <guid>https://dev.to/nicklevenson/building-a-multimedia-content-sharing-website-with-rails-1gce</guid>
      <description>&lt;p&gt;For a Flatiron School project I wanted to build a website that allowed users to create mixes/playlists and add multimedia content to them. I wanted the site to be social, where users could share their mixes, follow users, comment, and like posts. This post is meant to walk readers through the process of creating this website. Ruby on Rails let's go!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://memix.herokuapp.com/" rel="noopener noreferrer"&gt;The website&lt;/a&gt; is hosted on Heroku - feel free to check it out and make an account! Also, feel free to check the code out on &lt;a href="https://github.com/nicklevenson/me-mix-3" rel="noopener noreferrer"&gt;github&lt;/a&gt;. Video walk through can be found &lt;a href="https://drive.google.com/file/d/1Wbi01rJem66jXHCgdToq2w5VS2XNPDVQ/view?usp=sharing" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 1: APIS and Scraping&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Utilizing 4 apis (Spotify, Omdb, Google Books, the MET) and 1 scraper (the Poetry Foundation), I was able to create a search engine for these media types. Learning to use these apis was a great learning experience for using api keys and handling data. For spotify, there was a handy ruby gem called 'rspotify' that made queries easy. Likewise with Omdb, I used a handy gem called 'omdb-api' to help access their open database. I manually fetched data from the MET's open database as well as the google books api. For poetry, I ended up scraping the Poetry Foundation's website. Here's an example of how I configured the Spotify api, as well as the poetry scraper: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz6f792koiflnrblog4bd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz6f792koiflnrblog4bd.png" alt="Alt Text" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F67t7v9tvgy9694w3g79s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F67t7v9tvgy9694w3g79s.png" alt="Alt Text" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look close you may see that I transferred the data from each api into an object that has the same attributes. This was to normalize the data across all the apis, so I could create one model called 'Content' that could be any type of media. More on this in the next section. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2: Plotting the DB and related models&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is the schema to the app. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvg87kew9g33b6mhemm60.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvg87kew9g33b6mhemm60.png" alt="Alt Text" width="800" height="1542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdz2khgmiqmuh6dzqu734.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdz2khgmiqmuh6dzqu734.png" alt="Alt Text" width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once I had figured out how to normalize the media data, I was able to create a model called Content to represent those objects. I made a User model which had many Mixes, and mixes had many Contents. However, Contents could belong to many mixes so I used a joins table called MixContent. Contents could also have Notes that Users added to them inside their Mixes. That meant the Note model was simply a joins table between Mix and Content. I also added other tables which allowed Users to like and comment on Mixes, as well as follow and be followed by other Users. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 3: The MVC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I think one of the most challenging parts of this project was the user interface. I had to make things clear so users could understand how to search for content and add it to their mixes. I ended up making a search bar where you could choose to search for items in every category, or you could filter the categories by type. I searched 'Dev Article' in all and these were the results I got. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F23zbq73wyaq1vie6ezqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F23zbq73wyaq1vie6ezqs.png" alt="Alt Text" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffvlgzu3tvf642yz9gny8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffvlgzu3tvf642yz9gny8.png" alt="Alt Text" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the pictures, you can see a space where users can select or create a new mix on a specific piece of content and then add that content to that new or existing mix. I used a datalist element for this feature. Implementing this part was definitely a challenge. Here's what the erb looks like for the datalist: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F99pss5nwfxmodg62rjsw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F99pss5nwfxmodg62rjsw.png" alt="Alt Text" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically, the form builds a new mix for the current user, as well as a new content for the mix. The new content data is being pulled from the api data that was sent from the apis/scraper. The datalist tag gives the user an option of selecting from their existing mixes or writing in a new mix. When the user hits the submit button, the controller persists the new content to a found or created mix for that particular user. &lt;/p&gt;

&lt;p&gt;Here's where a user can filter the results. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq9wslcjf60v5vu4if72g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq9wslcjf60v5vu4if72g.png" alt="Alt Text" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's what the code looks like in the controller for the search and filter: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm28v3598lk5t3z83iglq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm28v3598lk5t3z83iglq.png" alt="Alt Text" width="758" height="258"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6khek5b05sxuwfgek4gw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6khek5b05sxuwfgek4gw.png" alt="Alt Text" width="800" height="900"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsm7x9vul1k6tek78pw5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsm7x9vul1k6tek78pw5l.png" alt="Alt Text" width="800" height="1235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's going on here? Well, the controller is calling a helper method to get an array of results. The @lastresult bit is just checking the last filter the user submits so it will persist on a refresh. Inside the helper, we are checking what the filter is, and then calling from the different apis or Mixes to get results based on that search and filter. We also have some helper methods to check and see if the result is a mix or a content to help out with rendering in the views.  &lt;/p&gt;

&lt;p&gt;Users can also search in Mixes themselves. This query will return any mix who's title is similar to the query, as well as mixes who's content matches the query.&lt;/p&gt;

&lt;p&gt;There were a lot of other major challenges with the MVC, but these were probably the most important challenges I faced for the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 4: Prepping for Heroku&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Prepping for Heroku involved two major steps. I had to make my database a Postgres db. That part wasn't too difficult with the following code: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F81315oreb3nfls8hjlf8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F81315oreb3nfls8hjlf8.png" alt="Alt Text" width="800" height="930"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The harder part was the storage. I wanted my users to be able to upload photos to their profile if they wanted. Originally I was using active storage for this purpose, but because active storage uses a local disk, this wouldn't work properly on Heroku. I had to configure my storage to use amazon web services. It took a while to figure out but &lt;a href="https://medium.com/@iachieve80/rails-6-0-upload-images-using-active-storage-and-amazon-simple-storage-service-amazon-s3-36861c03dc4a" rel="noopener noreferrer"&gt;this article&lt;/a&gt; really helped me out. &lt;/p&gt;

&lt;p&gt;Once I figured all that out, I was pretty much good to go on Heroku!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Future plans:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While I did use Bootstrap for styling, I didn't use any javascript elsewhere. There are multiple features that would be great if the page didn't require a refresh. So learning to send ajax requests and have the page update without a refresh would be ideal. I tried using the new rails gem Hotwire, and it actually worked really well. I was able to make changes to the db with no refreshes. However, something about Hotwire was doing something to my ability to use Omniauth for logging in - something to do with the CORS policy. I couldn't figure out a way to get around this so I scratched using Hotwire and stuck with good ol page refreshes (Omniauth was required for this project). Next time Hotwire! &lt;/p&gt;

&lt;p&gt;I would also like to do some more styling and make the site ideal for small screen use. It works on a smartphone, but is not amazing. I could spend weeks adding more style features, but I only had a week to complete the project. &lt;/p&gt;

&lt;p&gt;Adding a notification system for users would be awesome, but I didn't have time to figure that out. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This project was extremely challenging and really pushed my limits on how much I could get done in such a small amount of time. However, I learned a plethora of things and I am proud of what I created. I hope the site can attract more users because I genuinely believe in its use case. I love getting a glance into other people's taste in these media categories. I hope you found this article helpful, and would always appreciate constructive feedback on the project. There was a lot to cover and I only scratched the surface of the inner workings of my app. I would be happy to answer any questions readers may have. &lt;/p&gt;

&lt;p&gt;Thank you for reading! &lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>api</category>
      <category>database</category>
    </item>
    <item>
      <title>Building a Web Application with Sinatra</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Sat, 12 Dec 2020 00:03:42 +0000</pubDate>
      <link>https://dev.to/nicklevenson/my-first-web-application-25lj</link>
      <guid>https://dev.to/nicklevenson/my-first-web-application-25lj</guid>
      <description>&lt;p&gt;Welcome to Recipe Freak, my first &lt;a href="https://recipe-freak.herokuapp.com/" rel="noopener noreferrer"&gt;web application&lt;/a&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkxtk2vr4teujcnsv7y84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkxtk2vr4teujcnsv7y84.png" alt="Alt Text" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My first web app, built in Sinatra, allows users to create, share, and do other fun things with recipes. It's essentially a social media for recipes. &lt;/p&gt;

&lt;p&gt;A video walkthrough can be found &lt;a href="https://drive.google.com/file/d/1UA1V9tlh0dKzORnZs6XfSYd-My1EVbeu/view?usp=sharing" rel="noopener noreferrer"&gt;here:&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is my second Flatiron School project, and my first web application. I started my app with the gem 'corneal' which gave a very convenient template for a Sinatra/ActiveRecord based, application. From there, I tweaked things to what I wanted. I began by outlining my application, defining all the models and their relationships. It was tough to decide what should be attributes and what should be separate models, but I figured that making more models would give me more flexibility down the road. Though they weren't perfect at first, the relationships ended up being as follows: &lt;/p&gt;

&lt;p&gt;User: -has_many :recipes, has_many :likes&lt;/p&gt;

&lt;p&gt;Recipe: -belongs_to :user, belongs_to :cuisine, has_many :steps, :has_many likes, :has_many bags&lt;/p&gt;

&lt;p&gt;Cuisine: has-many :recipes&lt;/p&gt;

&lt;p&gt;Ingredients: belongs_to :recipe&lt;/p&gt;

&lt;p&gt;Steps: belongs_to :recipe&lt;/p&gt;

&lt;p&gt;Likes: belongs_to :recipe, belongs_to :user&lt;/p&gt;

&lt;p&gt;Bag(for a feature of adding a recipe to a grocery list): belongs_to :recipe, belongs_to :user&lt;/p&gt;

&lt;p&gt;Once the relationships were created, it was time to create database migrations to fit these models. After that, it was time to work on views and controllers. I didn't feel like working on migrations or controllers was that difficult, but the views proved to be an excellent challenge. &lt;/p&gt;

&lt;p&gt;Using erb files was liberating since I could embed ruby code and send instance variables from the controllers to the views. I also included a few JavaScript functions for the front end to manipulate the DOM. I had to let the user dynamically add and delete ingredients, as well as adjust serving sizes for recipes. JavaScript was my only viable option for this. I also spent a long time with CSS styling, which was surprisingly difficult. I am sure once I start digging into CSS/JS fundamentals it will become more intuitive to organize my html elements for styling and DOM manipulation. &lt;/p&gt;

&lt;p&gt;I learned so much from this project. having learned the concepts of http and routing, MVC, user authentication, good object oriented design, and more - the past few weeks have been a tsunami of information. However, I am understanding it more everyday. I ended up pushing my app to Heroku, which was the most exciting part of the project. I am so excited for the future and projects to come. &lt;/p&gt;

&lt;p&gt;If you're interested in checking out the code, view it on github &lt;a href="https://github.com/nicklevenson/recipe_freak" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>mvc</category>
      <category>flatiron</category>
      <category>heroku</category>
    </item>
    <item>
      <title>My First Project at Flatiron School</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Fri, 13 Nov 2020 16:28:24 +0000</pubDate>
      <link>https://dev.to/nicklevenson/my-first-project-at-flatiron-school-18a5</link>
      <guid>https://dev.to/nicklevenson/my-first-project-at-flatiron-school-18a5</guid>
      <description>&lt;p&gt;Flatiron's first project tasked me with creating a CLI app in Ruby. The app had to fetch data from an outside source, use proper object orientation, and let the user interact with the command line to retrieve specific data. I love space. So I chose to use the Open Solar System API as my data source, and I built my application to display different kinds of data about all the planets and moons in our solar system based on what the user wants to see. &lt;/p&gt;

&lt;p&gt;There were two major challenges I had to overcome when building this project. The first was using the API and retrieving the data I desired. The second was organizing and instantiating my objects. Once I had these two steps done, the next steps were a little more straightforward - getting user input and displaying object attributes in a user friendly form. &lt;/p&gt;

&lt;p&gt;My API class was designed to initialize with the API url I was using. I then created methods using the gems 'httparty' and 'json' to parse through the json objects I was getting to return an array of hashes (and some with nested hashes). After that, I parsed through each hash, each containing keys and values pertaining to a celestial object, and instantiated new planet and moon objects. I had to determine whether the hash was a planet or a moon, then create a new planet or moon instance, passing through the hash of data for that specific object.  &lt;/p&gt;

&lt;p&gt;API retrieval/creating new objects in action:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvoabp3mq2owcrsxma0ho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvoabp3mq2owcrsxma0ho.png" alt="Alt Text" width="451" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I decided to make two separate, but related classes. One for planets and one for moons. The API class would automatically pass in each planet and moon hash to its corresponding class. Each class uses meta-programming to initialize an object and create attribute accessors for each key in the hash, and set those attributes equal to the values. This meant I didn't have to manually set every attribute for the new objects. I knew that each planet object should have many moons. That meant that in the moon class, I had to iterate through all the planet objects to find which planet that specific moon instance belongs to. In doing this, I set up a has-many relationship where a planet has-many moons, and each moon knows about the planet instance it belongs to.&lt;/p&gt;

&lt;p&gt;Meta-programming/Mass Assignment in action:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0lbvve9ipf46uzs1h4fq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0lbvve9ipf46uzs1h4fq.png" alt="Alt Text" width="276" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That was the heavy lifting. The rest was straightforward - displaying information, getting a user input, displaying more information, etc.. In the end, a user could enter any planet they wanted to know more about, and then decide to get a list of its moons, or get its mass, density, and many other details. When a user decided to list a planet's moons, they would see every moon that a planet had in its orbit, along with an option to enter a moon they wanted to know more about. If so, the user could find out details about any moon. &lt;/p&gt;

&lt;p&gt;After completing this project, I feel very confident with accessing data from an API and object orientated programming and design. I am currently learning how to turn my app into a Ruby gem so anyone can use it easily. &lt;/p&gt;

&lt;p&gt;If you want to check out the project on github, see this link: &lt;a href="https://github.com/nicklevenson/solar-system-cli" rel="noopener noreferrer"&gt;https://github.com/nicklevenson/solar-system-cli&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ruby</category>
      <category>cli</category>
      <category>oop</category>
    </item>
    <item>
      <title>Why I Decided to Study Software Engineering</title>
      <dc:creator>nicklevenson</dc:creator>
      <pubDate>Mon, 19 Oct 2020 18:47:12 +0000</pubDate>
      <link>https://dev.to/nicklevenson/why-i-decided-to-study-software-engineering-40li</link>
      <guid>https://dev.to/nicklevenson/why-i-decided-to-study-software-engineering-40li</guid>
      <description>&lt;p&gt;Why did I decide to learn software engineering? The short and cliche answer is:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Balance&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg8o6dh92bym4k56q5i4u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg8o6dh92bym4k56q5i4u.jpg" alt="Alt Text" width="781" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I consider myself to have a creative heart. Since I was little I have loved project oriented hobbies. As a kid I was obsessed with medieval weaponry, trying to build a trebuchet or crossbow out of household items. Running the constant risk of getting parentally scolded, I frequently took apart my RC cars that I had just got for my birthdays, just to try to put it back together. This habit usually ended with a non-functional piece of junk, but I loved the way it felt when I got something to work. &lt;/p&gt;

&lt;p&gt;As I got older, my creative energy shifted from mechanical to more artistic and expressive. I learned to play and record music, which is still one of my favorite ways to spend time. Similar to building household gizmos as a kid, finishing a song and having people listen and enjoy gives me an immense feeling of accomplishment, satisfaction, and fulfillment. I made this, and it's mine. While attending college I studied film, philosophy, and music. After graduating I worked in television, but I found the work to be less fulfilling and less creative as I had expected in school. It was an exciting industry to be a part of, but I couldn't shake the feeling that something was missing. Then, the COVID pandemic hit, the industry was on pause, and I had a moment to sit back and reevaluate my life's direction. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;I looked to the things I loved and extracted the qualities that made them lovable.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Film and music were expressive and more abstract, while philosophy was logical. With time to reflect, I realized that I needed a career that was creative and that &lt;em&gt;balanced&lt;/em&gt; my logical and abstract qualities. I had taken a couple coding classes in college and was always interested in learning more. So during the start of the pandemic I decided to learn on my own. As it turned out, programming was exactly what I was looking for. It felt like a perfect &lt;em&gt;balance&lt;/em&gt; of problem solving and abstract creative thinking. Couple that with intense feelings of euphoria during those 'aha' moments in figuring something out and making something work, I knew programming was something I had to pursue seriously. A few months later and I find myself beginning Flatiron School's full time software engineering program. I know this journey will be extremely challenging, but I am beyond excited to delve into the world and career of programming.&lt;/p&gt;

</description>
      <category>student</category>
      <category>flatiron</category>
      <category>codenewbie</category>
      <category>career</category>
    </item>
  </channel>
</rss>
