<?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: Norman R.</title>
    <description>The latest articles on DEV Community by Norman R. (@nr598).</description>
    <link>https://dev.to/nr598</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%2F487791%2F2e8ad9fd-f224-4126-b1bc-3264368f7114.png</url>
      <title>DEV Community: Norman R.</title>
      <link>https://dev.to/nr598</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nr598"/>
    <language>en</language>
    <item>
      <title>Google login using OmniAuth in Rails</title>
      <dc:creator>Norman R.</dc:creator>
      <pubDate>Thu, 29 Jul 2021 10:49:48 +0000</pubDate>
      <link>https://dev.to/nr598/google-login-using-omniauth-in-rails-23fi</link>
      <guid>https://dev.to/nr598/google-login-using-omniauth-in-rails-23fi</guid>
      <description>&lt;p&gt;After receiving numerous requests (O.k. not really “numerous” more like 1) I decided to show how to set up Omni Auth to use Google logins with your rails app. There’s a ton of info floating around on how to do it but like a lot of things in tech the methods change and become outdated. I recently used it on a test project so I figured it can be of use to someone. It’s not overly complicated but there are many steps you need to follow to make it work properly. Ready? Cool. lets get it crackin’.&lt;br&gt;
    To start, head over to (&lt;a href="https://console.developers.google.com/"&gt;https://console.developers.google.com/&lt;/a&gt;) and click “OAuth consent screen” .  Select “create project” and at the next menu add a “project name”. Click “create” to confirm then scroll down to Application home page and enter your web apps URL. For today we will be using a local host so for example you can enter &lt;a href="https://localhost:3000"&gt;https://localhost:3000&lt;/a&gt;. Navigate to the “User type” form and select “external”. Next scroll to “Developer Contact information” and enter your email. Select “SAVE AND CONTINUE”. Navigate to the “Credentials” tab on the left and select “OAuth client ID”. Under “Application type” form, select “web application”. 2 new selection should appear at the bottom of the page. Select “URIs* under the “Authorized redirect URIs” In the form enter &lt;a href="http://localhost:3000/auth/google_oauth2/callback"&gt;http://localhost:3000/auth/google_oauth2/callback&lt;/a&gt;. Click save and continue. Once you finish creating the app your client id and secret should be listed. &lt;br&gt;
    Go back into your code editor and now we need to add 4 gems in your gemfile then run “bundle” in the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem 'omniauth'
gem 'omniauth-rails_csrf_protection'
gem 'omniauth-google-oauth2'
gem 'bcrypt'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create or select the file.&lt;br&gt;
&lt;strong&gt;config\initializers\omniauth.rb&lt;/strong&gt; and enter the following info.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
end
OmniAuth.config.allowed_request_methods = %i[get]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember when editing middleware its best to close and reload your puma server when you make changes.&lt;br&gt;
In your &lt;strong&gt;config\routes.rb&lt;/strong&gt; we will add a get route for oauth to use. Enter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get '/auth/google_oauth2/callback', to: 'sessions#google_auth'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next you need to create an env file for your google client ID and secret. In the root folder of your app make a new file called &lt;strong&gt;.env&lt;/strong&gt; enter the code then paste your secret and key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GOOGLE_CLIENT_ID = &amp;lt;id here&amp;gt;
GOOGLE_CLIENT_SECRET = &amp;lt;key here&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to add your secret and key to your gitignore file or the key will be exposed when the repo is pushed.&lt;br&gt;
Now head over to or create &lt;strong&gt;app\controllers\sessions_controller.rb&lt;/strong&gt; and add the following inside it.&lt;br&gt;
&lt;/p&gt;

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

  def google_auth
    @user = User.find_or_create_by(uid: auth['uid']) do |u|
      u.name = auth['info']['name']
      u.email = auth['info']['email']
      u.image = auth['info']['image']
      access_token = auth
      u.google_token = auth.credentials.token
      refresh_token = auth.credentials.refresh_token
      u.google_refresh_token = refresh_token if refresh_token.present?
      u.password = SecureRandom.urlsafe_base64
    end
    log_in @user
    redirect_to menu_path
  end

private

  def auth
    request.env['omniauth.auth']
  end

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

&lt;/div&gt;



&lt;p&gt;The last line after the first “end” command you can change based on how your routes are set up in your app. O.K. now head to &lt;strong&gt;app\controllers\application_controller.rb&lt;/strong&gt; and enter the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ApplicationController &amp;lt; ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to &lt;strong&gt;app\helpers\sessions_helper.rb&lt;/strong&gt; and enter the following.&lt;br&gt;
&lt;/p&gt;

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

  def log_in(user)
    session[:user_id] = user.id
  end

  def current_user
    current_user ||= User.find_by(id: session[:user_id])
  end

  def logged_in?
    !current_user.nil?
  end

  def log_out
    session.delete(:user_id)
    current_user = nil
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your views you can add this code for a login button.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;%= button_to "Sign in with Google", '/auth/google_oauth2', 
                    method: :get %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make the file &lt;strong&gt;db\migrate\001_create_users.rb&lt;/strong&gt; then enter the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CreateUsers &amp;lt; ActiveRecord::Migration[6.1]
  def change
    create_table :users do |t|
      t.string :name
      t.string :uid
      t.string :email
      t.string :google_token
      t.string :google_refresh_token
      t.string :image
      t.string :password_digest

      t.timestamps
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the terminal run&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and that’s it.  As of the date of this blog I can confirm this works so get it while it’s fresh!  Any questions or suggestions feel free to hit me up.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My First Program</title>
      <dc:creator>Norman R.</dc:creator>
      <pubDate>Thu, 05 Nov 2020 09:41:54 +0000</pubDate>
      <link>https://dev.to/nr598/my-first-program-3j6d</link>
      <guid>https://dev.to/nr598/my-first-program-3j6d</guid>
      <description>&lt;p&gt;After nearly a week and a half of trial an error I finally finished my first CLI project. It definitely took longer then expected mainly due to my lack of asking for help which I will make a priority for the next project. Completion of the this project really helped me change from a guy who just memorized a few ruby commands to a guy who can formulate ideas and convert them to "sloppy" but coherent code. I still have a long way to go and after struggling for weeks wondering if I actually "know" anything, I have gain a little more confidence.&lt;/p&gt;

&lt;p&gt;As a former truck driver one of the many annoying situations in the long haul industry is finding suitable parking for an 18 wheeler. I decided to make a Command Line Interface (CLI) program to help find trucks stops in different states.&lt;/p&gt;

&lt;p&gt;I first started building a flow chart that wasn't very well thought out and quickly ended up just "coding as I go". I decided to build the web scraper using nokogiri first which was my biggest challenge. It took a while to find a suitable web site to scrape since one of the project requirements was to use a 2 level web scrape. I settled on Allstays.com which had all the locations of truck stops in the US and Canada. The site was full of good info but I struggled finding the right CSS selectors. The site had the states on one page and the city and address on another. The state names and links were placed in "a" classes which made it easy to get to the next page. I wanted end users to be able to type in a state name and have the program match that with the data from the website. I used an "each do" loop to iterate through the css elements as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scrape.each do |element|
      @state_name = element.children.text
      @state_url = element['href'].insert(0, 'https:')
      if user_input == @state_name
        second_scrape(@state_url, user_input)
        return
      end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the user search match the css elements text then it would use the url as an argument for the second scrape method.  If your wondering what&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(0, 'https:')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 is well that is because the url was missing the "https" causing nokogiri to crash. Adding that to the beginning of each url the block iterated through allowed nokogiri to scrape the next web page successfully. Scraping data on the second page of the site was difficult as the truck stop address, name, and city were not together in a class like before. At first I tried to code an iterator using "each" but ended up with unwanted text from the site. After figuring out the text elements pattern I noticed the truck stop address was located every two elements apart and the city name was located one element apart. The name of the truck stop was in a separate "a" class. I wanted to iterate through all 3 elements at once and store them in newly created "Truckstop" class instances but the program kept crashing when I used an "each do" loop. I'm sure a better engineer could have done this in one or two lines of code but I decided to make a custom iterator using a "while" loop. The loop could iterate through all 3 elements at once even though they had different patterns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name_counter = -1
    address_counter = -2
    city_counter = -1
    while city_counter &amp;lt; city_scrape.length - 6
      city_counter += 1
      name_counter += 1
      address_counter += 2
      truckstop_city = city_scrape[city_counter].text
      truckstop_name = name_scrape[name_counter].text
      truckstop_address = address_scrape[address_counter].text
      truckstop = Truckstop.new(truckstop_name, truckstop_city, truckstop_address)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code isn't very sexy but it does the trick. The " - 6" above would stop the "address" iterator from overshooting the "city_scrape" array which would lead to an error as well as unwanted text found at the back of the array. I would have preferred to just store the values in a hash but the project required me to use class instances. One thing I never figured out was how to take a string value and use it to dynamically name a new instance class. The project deadline was approaching and being behind I skipped that task. If any one reading this know how to do that using meta programming or a command please reply below. Here is the Github link to the project. Thank you. &lt;a href="https://github.com/NR598/Cli_Project.git"&gt;Link&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Trucker 2 Coder: Why I am Becoming a  Software Engineer</title>
      <dc:creator>Norman R.</dc:creator>
      <pubDate>Mon, 12 Oct 2020 18:10:24 +0000</pubDate>
      <link>https://dev.to/nr598/trucker-2-coder-why-i-am-becoming-a-software-engineering-30im</link>
      <guid>https://dev.to/nr598/trucker-2-coder-why-i-am-becoming-a-software-engineering-30im</guid>
      <description>&lt;p&gt;A long-distance truck driver changing careers to software engineer probably does not happen very often if at all. Truckers are paid well and have plenty of stable work so why am I switching to software engineer? Here is my story.&lt;/p&gt;

&lt;p&gt;I have always been interested in computers since I was a kid. I remember trying to teach myself C++ and java when I was 12 just so I could make my own video games. The math and logic behind coding kind of scared me away from software development at that time. I ended up moving to New York for a few years living in a recording studio and producing mixtapes for local rappers. I started to build PCs for audio recording, and I became re-interested in coding. Again however, I ran away from it when it got too complicated.&lt;/p&gt;

&lt;p&gt;In 2010 a friend had convinced me move to California. I had no real plan I guess; just throw everything I could fit in my car and figure it out when I get there. With no job or any idea of what I was doing I ended up spending all the money I had with nothing to show for it. After a year of doing basically nothing I decided to get my CDL and became a truck driver. It seemed like a good way to earn a living and I did not have to worry about the job being outsourced or something. &lt;/p&gt;

&lt;p&gt;Around 2013 I finally landed a good, high paying job driving for Kroger and I moved to downtown Long Beach. Most people would probably assume life was good for me and technically it was at that point, but I was miserable. Life had become boring, repetitive and I was alone most of the time due to my 80-hour work weeks. Out of boredom and a little fear of A.I. replacing truckers, I started looking into learning coding again and that is when I heard about coding camps. It seemed too good to be true. A 3-month course that has a very high chance to get you a job in tech and is way cheaper than a computer science degree. I assumed it was a scam and ignored the e-mail.&lt;/p&gt;

&lt;p&gt;2016 was the year I finally decided to get a college degree. Just like before, I quit my job, threw everything in my car, and drove back to New Jersey. I planned to use all the money I made to pay for school and well let’s just say it didn’t happen that way. I got lazy and again blew it all hanging out and taking expensive trips. Now in my 30’s and broke again I ended up crawling back to the trucking industry. A couple years had passed, and I spent most of the time driving and listening to audio books on philosophy and computer science. All of the newfound knowledge inspired me to give computer science another go and this time I would stick with it. I started going to school in the morning and working as a trucker at night. I figured anything is possible if you work hard enough but I soon learned will power has its limits. I did well in school but my performance at my job got worse. I was tired and would show up late to work a lot. For the first time in life I ended up having a truck accident and got fired. I stopped going to school and started bouncing around between trucking, Uber and Amazon.  I still wanted to go back to college, but I felt that the computer science programs took too long. The courses were full of unnecessary and expensive classes. As an older guy who must work, I did not have flexibility to take all the classes I needed. I began looking for alternatives and found that coding camps were exactly what I was looking for. Fast-forward to 2020 and COVID has changed the lives of many. Work had dried up at my job and I sometimes spent days living in my truck unpaid waiting for loads. My priorities changed from working to school. After doing a lot of research on coding camps and if they are even useful, I decide to make another change in my life. I signed up for Flatirons fulltime online software courses and continued my journey to knowledge and purpose. &lt;/p&gt;

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