<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Allan</title>
    <description>The latest articles on Forem by Allan (@buildwithallan).</description>
    <link>https://forem.com/buildwithallan</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%2F412344%2F39eba294-d895-49a7-b5d6-d9aa31659fb6.jpg</url>
      <title>Forem: Allan</title>
      <link>https://forem.com/buildwithallan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/buildwithallan"/>
    <language>en</language>
    <item>
      <title>How To Set Up A Ruby On Rails CI Workflow Using Github Actions.</title>
      <dc:creator>Allan</dc:creator>
      <pubDate>Tue, 18 Jan 2022 04:11:16 +0000</pubDate>
      <link>https://forem.com/buildwithallan/how-to-set-up-a-ci-workflow-using-github-actions-4818</link>
      <guid>https://forem.com/buildwithallan/how-to-set-up-a-ci-workflow-using-github-actions-4818</guid>
      <description>&lt;p&gt;Continuous Integration(CI) is a development practice that enables developers to integrate code regularly into a central repository, where builds and tests run. The rationale behind this is that it helps development teams detect bugs quickly, improves code quality and security.&lt;/p&gt;

&lt;p&gt;There are several tools we can use to automate tests. Examples of such tools are GitHub Actions, CircleCI, and many more.&lt;/p&gt;

&lt;p&gt;This guide covers how you can set up a CI workflow for a Ruby on Rails app using GitHub Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  PREREQUISITES
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ruby On Rails app&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;GitHub Account&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  WHAT IS GITHUB ACTIONS?
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is an automation platform that helps developers to automate workflow. Since GitHub Actions come included in your GitHub projects, it is pretty easy to set up a CI workflow without relying on any third-party integrations. &lt;/p&gt;

&lt;h2&gt;
  
  
  COMPONENTS OF GITHUB ACTIONS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  WORKFLOW
&lt;/h3&gt;

&lt;p&gt;Workflow is an automated steps that is made up of one or more jobs that can be scheduled or triggered by an event. They are defined by a YAML file in the &lt;code&gt;.github/workflows&lt;/code&gt; directory and can be used to build, test, package, release or deploy a project on GitHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  EVENTS
&lt;/h3&gt;

&lt;p&gt;Events are specific tasks that trigger the execution of a workflow. An example is when you push a commit to a repository or create a pull request.&lt;/p&gt;

&lt;h3&gt;
  
  
  JOBS
&lt;/h3&gt;

&lt;p&gt;A job is a series of steps that executes on the same runner.&lt;/p&gt;

&lt;h3&gt;
  
  
  STEPS
&lt;/h3&gt;

&lt;p&gt;Steps consist of individual tasks to run a job. They group actions that are carried out on the runner.&lt;/p&gt;

&lt;h3&gt;
  
  
  ACTIONS
&lt;/h3&gt;

&lt;p&gt;Actions are the smallest building blocks of a workflow that are combined into steps to create a job. &lt;/p&gt;

&lt;h3&gt;
  
  
  RUNNERS
&lt;/h3&gt;

&lt;p&gt;A runner is a server on which our jobs will be executed.&lt;/p&gt;

&lt;h2&gt;
  
  
  CREATING A RUBY ON RAILS WORKFLOW
&lt;/h2&gt;

&lt;p&gt;I. Create a repository on GitHub.&lt;br&gt;
II. Create a new rails application, navigate to the directory, and push it to GitHub.&lt;br&gt;
III. Go to the repository, and in the &lt;code&gt;Actions&lt;/code&gt; tab, click on &lt;code&gt;setup a workflow yourself&lt;/code&gt;. By default, this will create folder &lt;code&gt;.github&lt;/code&gt;, a sub-folder &lt;code&gt;workflow&lt;/code&gt;, and a &lt;code&gt;main.yml&lt;/code&gt; file.&lt;br&gt;
IV. Commit this and run &lt;code&gt;git pull&lt;/code&gt; in the terminal to pull this.&lt;/p&gt;

&lt;p&gt;Now let's follow these steps to set up a CI workflow using GitHub Actions. &lt;/p&gt;
&lt;h3&gt;
  
  
  1. Name the workflow.
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: CI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2. Set the events.
&lt;/h3&gt;


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

  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this code snippet, the events will trigger the action to run whenever we push a code to the master branch or we perform a pull request. Note: The branch is set to the master branch by default, but you can configure it for different branches as well.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Define The Job.
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; jobs:
  test:
    runs-on: ubuntu-latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We define a job, give it a name and tell it to run on the latest version of ubuntu.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Define The Services.
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  services: 
      postgres:
        image: postgres:12
        env:
          POSTGRES_PASSWORD: postgres
        ports: ['5432:5432']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here, we specify the services we need to run the job and the database we need to run the tests.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Define the steps and Setup Dependencies
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;steps:
      - uses: actions/checkout@v2
      - name: Setup Ruby
        uses: ruby/setup-ruby@v1.80.0
        with:
          ruby-version: 2.6.6

      - uses: Borales/actions-yarn@v2.3.0
        with:
          cmd: install

      - name: Install Dependencies
        run: |
          sudo apt install -yqq libpq-dev
          gem install bundler

      - name: Install Gems
        run: |
          bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The code above checkouts the source code, sets up ruby with version 2.6.6, install gems, and Postgres dependencies.&lt;/p&gt;
&lt;h3&gt;
  
  
  6. Set up the database
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - name: Setup database
        env:
          PG_DATABASE: postgres
          PG_HOST: localhost
          PG_USER: postgres
          PG_PASSWORD: password
          RAILS_ENV: test
          WITH_COVERAGE: true
          DISABLE_SPRING: 1
        run: |
          bundle exec rails db:prepare
          bundle exec rake test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here we specify the database required for rails to create, run and connect to Postgres.&lt;/p&gt;
&lt;h3&gt;
  
  
  7. Add Rspec Test.
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - name: Build and test with RSpec
        env:
          PG_DATABASE: postgres
          PG_HOST: localhost
          PG_USER: postgres
          PG_PASSWORD: password
          RAILS_ENV: test
        run: |
          bundle exec rspec spec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Since we don't have RSpec included in the gemfile when we push the changes to GitHub we will have a failing workflow. Now, let's add &lt;code&gt;gem 'rspec-rails'&lt;/code&gt; to the gemfile 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; group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: %i[mri mingw x64_mingw]
  gem 'rspec-rails'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add some models and controllers to your app and write tests against them.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Add Code Coverage.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - name: Create Coverage Artifact
        uses: actions/upload-artifact@v2
        with:
          name: code-coverage
          path: coverage/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and in the gemfile add &lt;code&gt;gem 'simplecov', require: false&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '&amp;gt;= 3.26'
  gem 'selenium-webdriver'
  gem 'webdrivers'
  gem 'simplecov', require: false
end

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

&lt;/div&gt;



&lt;p&gt;This will generate a coverage report from the testing environment.&lt;/p&gt;

&lt;p&gt;Here is the complete workflow file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: CI
on:

  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  test:
    runs-on: ubuntu-latest

    services: 
      postgres:
        image: postgres:12
        env:
          POSTGRES_PASSWORD: postgres
        ports: ['5432:5432']

    steps:
      - uses: actions/checkout@v2
      - name: Setup Ruby
        uses: ruby/setup-ruby@v1.80.0
        with:
          ruby-version: 2.6.6

      - uses: Borales/actions-yarn@v2.3.0
        with:
          cmd: install

      - name: Install Dependencies
        run: |
          sudo apt install -yqq libpq-dev
          gem install bundler

      - name: Install Gems
        run: |
          bundle install

      - name: Setup database
        env:
          PG_DATABASE: postgres
          PG_HOST: localhost
          PG_USER: postgres
          PG_PASSWORD: password
          RAILS_ENV: test
          WITH_COVERAGE: true
          DISABLE_SPRING: 1
        run: |
          bundle exec rails db:prepare
          bundle exec rake test

      - name: Build and test with rspec
        env:
          PG_DATABASE: postgres
          PG_HOST: localhost
          PG_USER: postgres
          PG_PASSWORD: password
          RAILS_ENV: test
        run: |
          bundle exec rspec spec

      - name: Create Coverage Artifact
        uses: actions/upload-artifact@v2
        with:
          name: code-coverage
          path: coverage/



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

&lt;/div&gt;



&lt;p&gt;Now, commit this to the repository and push the file to GitHub. Go to the Actions tab, and in the Actions logs click on the latest build that outputs the name of each step in the workflow file. Be sure that the test runs successfully when you push a code to GitHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  CONCLUSION
&lt;/h3&gt;

&lt;p&gt;In this guide, we demonstrated how to set up a CI workflow using GitHub Actions. I hope you learned a lot, and thanks for following along.&lt;/p&gt;

&lt;h3&gt;
  
  
  REFERENCES
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions"&gt;https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.driftingruby.com/episodes/github-actions"&gt;https://www.driftingruby.com/episodes/github-actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>ci</category>
    </item>
    <item>
      <title>A Simple Authentication with Ruby On Rails</title>
      <dc:creator>Allan</dc:creator>
      <pubDate>Thu, 29 Jul 2021 11:46:32 +0000</pubDate>
      <link>https://forem.com/buildwithallan/a-simple-authentication-with-ruby-on-rails-2g4</link>
      <guid>https://forem.com/buildwithallan/a-simple-authentication-with-ruby-on-rails-2g4</guid>
      <description>&lt;p&gt;When building a web app, you don't want every user to have access to every single part of the app, so you will want to restrict access. That's why we add authentication to our app. In this tutorial, we will create a simple authentication for your Ruby On Rails app. &lt;/p&gt;

&lt;h2&gt;
  
  
  PREREQUISITES
&lt;/h2&gt;

&lt;p&gt;To follow along with this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some basic knowledge of Ruby On Rails&lt;/li&gt;
&lt;li&gt;A text editor(I am using &lt;a href="https://www.sublimetext.com/"&gt;sublime text&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt;, &lt;a href="https://rubygems.org/gems/rails"&gt;Rails&lt;/a&gt;, &lt;a href="https://nodejs.org/en/"&gt;Node&lt;/a&gt; and &lt;a href="https://classic.yarnpkg.com/en/"&gt;Yarn&lt;/a&gt; installed on your computer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SET UP
&lt;/h2&gt;

&lt;p&gt;To get started, create a new rails application and navigate to the directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails new authentication
cd authentication 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create a welcome page and set the root to index action in &lt;code&gt;WelcomeController&lt;/code&gt;.   &lt;/p&gt;

&lt;h3&gt;
  
  
  WELCOME PAGE
&lt;/h3&gt;

&lt;p&gt;To do this, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g controller welcome index

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

&lt;/div&gt;



&lt;p&gt;Now, let's set up the route in &lt;code&gt;config/routes.rb&lt;/code&gt; 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;Rails.application.routes.draw do

  get 'welcome', to: 'welcome#index'
  root to: 'welcome#index'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generator creates a &lt;code&gt;welcome_controller.rb&lt;/code&gt; file in &lt;code&gt;app/controllers&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

  def index
  end

end

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

&lt;/div&gt;



&lt;p&gt;It also creates an &lt;code&gt;index.html.erb&lt;/code&gt; file in &lt;code&gt;app/views/welcome&lt;/code&gt;. By default, rails render a view that corresponds with the name of the controller. Now, add some content for that page in the file:&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;h1&amp;gt;Welcome Page&amp;lt;/h1&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  BCRYPT
&lt;/h2&gt;

&lt;p&gt;In the database, we will not like to store our passwords in plain text. Instead, we encrypt the password. We can do this by uncommenting &lt;code&gt;gem 'bcrypt', '~&amp;gt; 3.1.7'&lt;/code&gt; in  &lt;code&gt;Gemfile&lt;/code&gt; and run &lt;code&gt;bundle install&lt;/code&gt; to install the gem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem 'bcrypt', '~&amp;gt; 3.1.7'
bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's continue by adding the model and controllers.&lt;/p&gt;

&lt;h2&gt;
  
  
  MODEL
&lt;/h2&gt;

&lt;p&gt;Create a user model with attributes, &lt;code&gt;email&lt;/code&gt; and &lt;code&gt;password_digest&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g model User email:string password_digest:string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run &lt;code&gt;rails db:migrate&lt;/code&gt; to migrate it to the database. The &lt;code&gt;email&lt;/code&gt; stores the email address of the user. Also, &lt;code&gt;password_digest&lt;/code&gt; creates a password_digest field in the users table.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;app/models/user.rb&lt;/code&gt;, add &lt;code&gt;has_secure_password&lt;/code&gt; and some validations.&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_secure_password

    validates :email , presence: true, uniqueness: true
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, before a user gets saved to the database, an email should be present, and it should also be unique.&lt;/p&gt;

&lt;h3&gt;
  
  
  REGISTRATION CONTROLLER
&lt;/h3&gt;

&lt;p&gt;Let's create a registration controller by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g controller registrations new 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following to &lt;code&gt;app/controllers/registrations_controller.rb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class RegistrationsController &amp;lt; ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)

    if @user.save
      session[:user_id] = @user.id
      redirect_to root_path
      else
       render :new  
    end
  end

  private

  def user_params
    params.require(:user).permit(:email, :password, :password_confirmation)
  end
end

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

&lt;/div&gt;



&lt;p&gt;The code snippet above creates a new user and saves it to the database. The &lt;code&gt;new&lt;/code&gt; action initializes a new object in the User model and stores it as an instance variable that can be accessed in the views. The &lt;code&gt;create&lt;/code&gt; action creates the user instance and sets its id to a session which redirects to the &lt;code&gt;root_path&lt;/code&gt; if successful and renders &lt;code&gt;new&lt;/code&gt; when it fails.&lt;/p&gt;

&lt;p&gt;Create a sign_up form in  &lt;code&gt;app/views/registrations/new.html.erb.&lt;/code&gt;&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;%= form_with model: @user, url: sign_up_path do |f|  %&amp;gt;
    &amp;lt;%= f.label :email %&amp;gt;
    &amp;lt;%= f.text_field :email %&amp;gt;

    &amp;lt;%= f.label :password %&amp;gt;
    &amp;lt;%= f.password_field :password %&amp;gt;

    &amp;lt;%= f.label password_confirmation %&amp;gt;
    &amp;lt;%= f.password_field :password_confirmation %&amp;gt;

    &amp;lt;%= f.submit "Sign Up" %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and update the route:&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.routes.draw do

  get 'welcome', to: 'welcome#index'
  root to: 'welcome#index'

  resources :users

  get 'sign_up', to: 'users#new'
  post 'sign_up', to: 'users#create'

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

&lt;/div&gt;



&lt;p&gt;Now, run &lt;code&gt;$ rails s&lt;/code&gt; to start the development server and visit &lt;code&gt;localhost:3000/sign_up&lt;/code&gt; to create a new user.&lt;/p&gt;

&lt;h3&gt;
  
  
  SESSIONS CONTROLLER
&lt;/h3&gt;

&lt;p&gt;Create the sessions controller by running the code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rails g controller sessions new create destroy&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and add the following code to &lt;code&gt;app/controllers/sessions_controller.rb&lt;/code&gt;:&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 new
  end

  def create
    user = User.find_by(email: params[:email])

    if user.present? &amp;amp;&amp;amp; user.authenticate(params[:password])
       session[:user_id] = user.id
       redirect_to root_path
    else
        render :new
    end
  end

  def destroy
    session[:user_id] = nil
    redirect_to sign_in_path
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;create&lt;/code&gt; method for &lt;code&gt;SessionsController&lt;/code&gt; finds the user based on the email in the database. If a user is present and the password matches, the id of the user instance is stored in a session and they are logged in. Otherwise, we will be redirected to the sign_in page.&lt;br&gt;
The &lt;code&gt;destroy&lt;/code&gt; method sets the user session to nil and logs out the user.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;app/views/sessions/new.html.erb&lt;/code&gt;, add:&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;h1&amp;gt;Sign In &amp;lt;/h1&amp;gt;

&amp;lt;%= form_with url: sign_in_path do |f| %&amp;gt;

    &amp;lt;%= f.label :Email %&amp;gt;
    &amp;lt;%= f.text_field :email %&amp;gt;

    &amp;lt;%= f.label :Password %&amp;gt;
    &amp;lt;%= f.password_field :password %&amp;gt;

    &amp;lt;%= f.submit "Sign in" %&amp;gt;
&amp;lt;% end %&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;and set up the routes:&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.routes.draw do

  get 'welcome', to: 'welcome#index'
  root to: 'welcome#index'

  resources :users

  get 'sign_up', to: 'users#new'
  post 'sign_up', to: 'users#create'

  get 'sign_in', to: 'sessions#new'
  post 'sign_in', to: 'sessions#create'
  delete 'logout', to: 'sessions#destroy'

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

&lt;/div&gt;



&lt;p&gt;Now, a user can sign_in by visiting &lt;code&gt;localhost:3000/sign_in&lt;/code&gt; in the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Current.user
&lt;/h3&gt;

&lt;p&gt;Add the following in &lt;code&gt;app/controllers/application_controller.rb&lt;/code&gt; to create a &lt;code&gt;Current.user&lt;/code&gt;&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
    before_action :set_current_user

    def set_current_user
      if session[:user_id]
       Current.user = User.find_by(id: session[:user_id])   
      end
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;set_current_user&lt;/code&gt; method will return the current user if it finds one or if there is a session present. Also, since all controllers inherit from the &lt;code&gt;ApplicationController&lt;/code&gt;, &lt;code&gt;set_current_user&lt;/code&gt; will be accessible in all the controllers.&lt;/p&gt;

&lt;p&gt;Let's create a &lt;code&gt;current.rb&lt;/code&gt; file in &lt;code&gt;app/models&lt;/code&gt; and add 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 Current &amp;lt; ActiveSupport::CurrentAttributes

  attribute :user

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

&lt;/div&gt;



&lt;p&gt;This code will allow us to call &lt;code&gt;Current.user&lt;/code&gt; in our views. &lt;/p&gt;

&lt;p&gt;Now, Open &lt;code&gt;app/views/welcome/index.html.erb&lt;/code&gt; and update it with 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;&amp;lt;h1&amp;gt;Welcome Page&amp;lt;/h1&amp;gt;

&amp;lt;% if Current.user %&amp;gt;
  Logged in as: Current.user.email&amp;lt;br&amp;gt;
  &amp;lt;%= button_to "Sign Out", logout_path,  method: :delete %&amp;gt;
  &amp;lt;% else %&amp;gt;
  &amp;lt;%= link_to "Sign up", sign_up_path %&amp;gt;
  &amp;lt;%= link_to "Sign In", sign_in_path %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code checks if &lt;code&gt;Current.user&lt;/code&gt; is present and provides a &lt;code&gt;sign_out&lt;/code&gt; button when signed in. Otherwise, a &lt;code&gt;sign_up&lt;/code&gt; and &lt;code&gt;sign_in&lt;/code&gt; link is seen.&lt;/p&gt;

&lt;h3&gt;
  
  
  CONCLUSION
&lt;/h3&gt;

&lt;p&gt;Congrats, we have successfully built a simple authentication in Ruby On Rails without relying on any gem. I hope you found this tutorial easy to follow, and If you have any questions, please add your query in the comments section. Thank you!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>authentication</category>
    </item>
    <item>
      <title>AN INTRODUCTION TO STIMULUS.JS</title>
      <dc:creator>Allan</dc:creator>
      <pubDate>Thu, 29 Apr 2021 15:05:13 +0000</pubDate>
      <link>https://forem.com/buildwithallan/an-introduction-to-stimulus-js-ik1</link>
      <guid>https://forem.com/buildwithallan/an-introduction-to-stimulus-js-ik1</guid>
      <description>&lt;h3&gt;
  
  
  INTRODUCTION
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/hotwired/stimulus"&gt;Stimulus.js&lt;/a&gt; is a modest JavaScript framework for the HTML you already have by connecting JavaScript objects(controllers) to the HTML on the page in an organized way.&lt;/p&gt;

&lt;p&gt;Unlike other JavaScript frameworks, it doesn't take over your entire front-end's application. The Basecamp team created it to simplify the problem of heavy frontend-driven architecture that's currently in vogue.&lt;/p&gt;

&lt;p&gt;This article will introduce you to stimulus.js by creating a slideshow and how it can help structure an application's front-end codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  PREREQUISITE
&lt;/h3&gt;

&lt;p&gt;For this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A basic understanding of HTML.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://classic.yarnpkg.com/en/"&gt;Yarn&lt;/a&gt; installed on your P.C&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  HOW STIMULUS.JS DIFFERS FROM MODERN JAVASCRIPT FRAMEWORKS
&lt;/h3&gt;

&lt;p&gt;Stimulus.js differs from modern JavaScript frameworks that are available today. It doesn't render templates like these modern JavaScript frameworks that rely on turning JSON into DOM elements via a template language. It relies on the DOM to hold the state. It also connects actions and events on the front-end of an application to controllers on the backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  CORE CONCEPTS
&lt;/h3&gt;

&lt;p&gt;Stimulus.js has three(3) main concepts. These are controllers, actions, and targets. Here’s an example of code you’ll write to copy text from an input field to the clipboard:&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;div data-controller="clipboard"&amp;gt;
  PIN: &amp;lt;input data-clipboard-target="source" type="text" value="1234" readonly&amp;gt;
  &amp;lt;button data-action="clipboard#copy"&amp;gt;Copy to Clipboard&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the accompanying JavaScript 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;#clipboard_controller.js

import {Controller} from "stimulus"

export default class extends Controller{
    static targets = ['source']
    copy(){
        this.sourceTarget.select()
        document.execCommand('copy')
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Controllers
&lt;/h3&gt;

&lt;p&gt;Controllers refer to instances of JavaScript classes that you define in your application. The &lt;code&gt;data-controller&lt;/code&gt; attribute connects the HTML to the JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Actions
&lt;/h3&gt;

&lt;p&gt;Think of actions as a way of handling DOM events in your controller. In the clipboard markup, the data attribute &lt;code&gt;data-action="clipboard#copy"&lt;/code&gt; copies the text when we click on the button in the HTML and runs the action &lt;code&gt;copy&lt;/code&gt; in the controller.&lt;/p&gt;

&lt;h3&gt;
  
  
  Targets
&lt;/h3&gt;

&lt;p&gt;Targets let you define essential elements that will be available to your controller.  The &lt;code&gt;data-clipboard-target=" source"&lt;/code&gt; sets up a target with the name &lt;code&gt;source&lt;/code&gt; in the controller, and we can access this by using &lt;code&gt;this.sourceTarget&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  GETTING STARTED
&lt;/h3&gt;

&lt;p&gt;To get started, you need to clone and set up &lt;code&gt;stimulus-starter&lt;/code&gt;. You can do this by using the commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/hotwired/stimulus-starter.git
$ cd stimulus-starter
$ yarn install
$ yarn start

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

&lt;/div&gt;



&lt;p&gt;Then visit &lt;code&gt;http://localhost:9000/&lt;/code&gt; in your browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  CREATING A SLIDESHOW WITH STIMULUS.JS
&lt;/h3&gt;

&lt;p&gt;In this section, I will demonstrate how to create a slideshow using stimulus.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  CREATING A CONTROLLER
&lt;/h3&gt;

&lt;p&gt;Open the index file in the public directory and update it with this code.&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;div data-controller="slideshow"&amp;gt;

 &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;stimulus-starter&lt;/code&gt;, there is a controller folder so let's create a file &lt;code&gt;slideshow_controller.js&lt;/code&gt; and add this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller } from "stimulus"

export default class extends Controller {

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

&lt;/div&gt;



&lt;p&gt;Let's break down what's going on in the code snippets above.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;data-controller&lt;/code&gt; attribute connects our controller to the DOM with the identifier slideshow.&lt;/p&gt;

&lt;h3&gt;
  
  
  CONNECTING THE ACTION
&lt;/h3&gt;

&lt;p&gt;Now, let's add a button inside the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; to connect the action method to the button's &lt;code&gt;click&lt;/code&gt; event. We can do this by adding a &lt;code&gt;data-action&lt;/code&gt; attribute to the 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 data-action="click-&amp;gt;slideshow#previous" class="btn"&amp;gt; ← &amp;lt;/button&amp;gt;
    &amp;lt;button data-action="click-&amp;gt;slideshow#next" class="btn"&amp;gt;  → &amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have&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;div data-controller="slideshow"&amp;gt;
    &amp;lt;button data-action="click-&amp;gt;slideshow#previous" class="btn"&amp;gt; ← &amp;lt;/button&amp;gt;
    &amp;lt;button data-action="click-&amp;gt;slideshow#next" class="btn"&amp;gt;  → &amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in the controller, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller } from "stimulus"

export default class extends Controller {

  initialize() {
    this.index = 0
  }

  next() {
    this.index++
  }

  previous() {
    this.index--
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can look at the code snippet above and understand what is going on.&lt;br&gt;
The &lt;code&gt;data-action&lt;/code&gt; value &lt;code&gt;click-&amp;gt;slideshow#previous&lt;/code&gt; and &lt;code&gt;click-&amp;gt;slideshow#next&lt;/code&gt; are called action descriptors. The descriptor says that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;click&lt;/code&gt; is the name of the event&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;slideshow&lt;/code&gt; is the controller identifier&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;previous&lt;/code&gt;, &lt;code&gt;next&lt;/code&gt; are the names of the method&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;initialize&lt;/code&gt; method shows the first slide. The &lt;code&gt;next()&lt;/code&gt; and &lt;code&gt;previous()&lt;/code&gt; method in the controller advance and goes back to the current slide when we click on the button(for now, the button doesn't do anything when we click on it).&lt;/p&gt;
&lt;h3&gt;
  
  
  USING TARGETS
&lt;/h3&gt;

&lt;p&gt;Add the following in the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&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;div data-slideshow-target="slide"&amp;gt;slide 1&amp;lt;/div&amp;gt;
&amp;lt;div data-slideshow-target="slide"&amp;gt;slide 2&amp;lt;/div&amp;gt;
&amp;lt;div data-slideshow-target="slide"&amp;gt;slide 3&amp;lt;/div&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;We have this now.&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;div data-controller="slideshow"&amp;gt;
    &amp;lt;button data-action="click-&amp;gt;slideshow#previous" class="btn"&amp;gt; ← &amp;lt;/button&amp;gt;
    &amp;lt;button data-action="click-&amp;gt;slideshow#next" class="btn"&amp;gt;  → &amp;lt;/button&amp;gt;

    &amp;lt;div data-slideshow-target="slide"&amp;gt;slide 1&amp;lt;/div&amp;gt;
    &amp;lt;div data-slideshow-target="slide"&amp;gt;slide 2&amp;lt;/div&amp;gt;
    &amp;lt;div data-slideshow-target="slide"&amp;gt;slide 3&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we created a target by adding &lt;code&gt;data-slideshow-target&lt;/code&gt; with the value slide to the &lt;code&gt;div&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;Next, let's create a property for the target by adding slide to the target definition in the controller. Stimulus.js automatically creates a &lt;code&gt;this.slideTarget&lt;/code&gt; property to get the first element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import { Controller } from "stimulus"

 export default class extends Controller {

  static targets = [ "slide" ]

  initialize() {
    this.index = 0
  }

  next() {
    this.index++
  }

  previous() {
    this.index--
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's add a method &lt;code&gt;showCurrentSlide()&lt;/code&gt; which will loop through each slide target.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;showCurrentSlide() {
    this.slideTargets.forEach((element, index) =&amp;gt; {
      element.hidden = index != this.index
    })
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this does is it will loop through each slide target and toggles the &lt;code&gt;hidden&lt;/code&gt; attribute if its index matches.&lt;/p&gt;

&lt;p&gt;Update the &lt;code&gt;slideshow_controller.js&lt;/code&gt; like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller } from "stimulus"

export default class extends Controller {
  static targets = [ "slide" ]

  initialize() {
    this.index = 0
    this.showCurrentSlide()
  }

  next() {
    this.index++
    this.showCurrentSlide()
  }

  previous() {
    this.index--
    this.showCurrentSlide()
  }

  showCurrentSlide() {
    this.slideTargets.forEach((element, index) =&amp;gt; {
      element.hidden = index != this.index
    })
  }
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can reload the page in the browser and confirm that the previous or next button goes back or advances to the next slide.&lt;/p&gt;

&lt;h3&gt;
  
  
  CONCLUSION
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we learn't what stimulus.js is, the core concepts, and demonstrated how to create a slideshow.&lt;/p&gt;

</description>
      <category>stimulus</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
