前回の自宅のwindowsでRuby on Rails(基礎編)では、最も基本的なRailsのWebアプリケーションを作成しました。
Railsが非常にスピーディーに、かつ簡潔に開発できるということが分かったのですが、Gemを理解すればもっと複雑なことを簡単に実行できると思います。
ということで今回は、新たに新しい機能を実装しつつ、RubyのGemについて学習して行こうと思います。

自宅のWindowsでRuby on Rails ~ Gemを理解する
1. Gemとは?
Gemは、Rubyコミュニティが作成した多数のライブラリやフレームワークを簡単にインストールしたり、アップグレードしたりできるようにすることで、Rubyの開発を促進しています。
Gemを使用することで、ライブラリやフレームワークを簡単にインストールできます。
通常、gemコマンドを使用して、Rubyのコマンドラインからインストールします。
たとえば、以下のコマンドを使用して、Railsフレームワークをインストールすることができます。
gem install railsつまり、RailsもRubyのGemの一つなのです。
また、Gemfileと呼ばれるファイルを使用して、プロジェクトに必要なGemを一括でインストールすることができます。
これは、プロジェクトごとに異なるGemを使用する場合に便利です。Gemfileには、必要なGemの名前やバージョンが記載されています。
Gemfileがある場所で、以下のコマンドを使用して、必要なGemをインストールできます。
bundle installbundle installコマンドを実行したあとは、ローカルサーバーを再起動します。
Gemはローカルサーバーを起動するときに読み込まれるからです。
2. 今回作成するWebアプリ
前回に引き続き、今回も簡単なアプリを作成します。
以下のような仕様にします。
・index
ユーザーログインボタンとユーザー新規登録ボタンを作ります。
新規文章投稿ボタンを作ります。新規文章投稿ボタンはユーザーがログインしていないと表示されないようにします。
一覧には、投稿文章と日付、投稿したユーザー名を表示します。一覧のリンクを押下することで、詳細画面に遷移します。
・show
詳細画面には、文章を投稿したユーザー名、日付、投稿された文章の全文を表示します。ログインしているユーザーが投稿者だった場合、編集ボタン、削除ボタンを表示させます。
・new
新規文章投稿のためのフォームを表示します。
・create
「投稿完了」画面を表示します。
・edit
投稿した文章を編集するためのフォームを表示します。
・update
「編集完了」画面を表示します。
・destroy
「削除完了」画面を表示します。
投稿文章のモデル名をPost、ユーザー情報のモデル名をUserとします。
Userモデルの作成には、Gemである、「devise」を使用します。
早速実装していきましょう。
3. 実装

3-1. 1.rails new
rails new second_app -d mysql
# 作成したsecond_appのディレクトリに移動
cd second_app
# 現在のディレクトリのパスを表示
pwd
3-2. 2.データベースの作成
rails db:create 
一旦ローカルサーバーを起動します。
rails s
3-3. 3.モデルを作成する
rails g model post
3-4. 4.「devise」Gemの導入
「devise」は、Ruby on Railsアプリケーションで認証機能を簡単に実装するためのGemです。
ユーザー認証、パスワードのリセット、アカウントのロック、サインアップ時の確認など、一般的な認証機能が簡単に実装できます。
また、標準的な機能に加えて、拡張性に優れたカスタマイズが可能で、多言語対応も可能です。
これにより、アプリケーション開発の効率を向上させ、セキュリティも確保することができます。
・Gemfileの編集
Gemfileの最後の行に、以下のコードを追加します。gem 'devise' 
・「devise」Gemのインストール
コマンドで、bundle installを実行します。bundle install 
インストールされたら、ローカルサーバーを起動します。
(一度起動させたら停止してもいいです)
rails s次に、以下のコマンドを実行します。
rails g devise:install 
・Userモデルの作成
deviseでUserモデルを作成します。以下のコマンドを実行します。
rails g devise user 
以上の操作で、Userモデルとマイグレーションファイルが自動的に作成され、config/routes.rbに以下のルーティングが自動で追記されました。
Rails.application.routes.draw do
  devise_for :users
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
3-5. 5.マイグレーション
今回は、rails g model postで作成したPostテーブルと、rails g devise userで作成したUserテーブルの二つの設定を行います。
まずはPostテーブルにnameカラムとcontentカラムを追加するため、db/migrate/XXXX_create_posts.rbを以下のように編集します。
class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
      t.string :name
      t.text :content
      t.references :user, null: false, foreign_key: true
      t.timestamps
    end
  end
end次は、Userテーブルの編集ですが、今回はdeviseによって自動生成されたマイグレーションファイルのままでいいので、編集はしません。
ちなみに、db/migrate/XXXX_devise_create_userss.rbがそれにあたります。
コマンドで、rails db:migrateを実行します。
rails db:migrate 
最後に、アソシエーションを行います。
アソシエーションとは、モデルを利用したテーブル同士の関連付けのことです。
app/models/post.rb
class Post < ApplicationRecord
  belongs_to :user
endapp/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  has_many :posts
end上記のコードにおいて、User モデルと Post モデルの間には、以下のようなアソシエーションが定義されています。
User モデルは、has_many :posts というメソッドによって Post モデルと関連付けられています。
これは、User インスタンスが複数の Post インスタンスを所有できることを表しています。
一方で、Post モデルは、belongs_to :user というメソッドによって User モデルと関連付けられています。
これは、Post インスタンスが必ず1つの User インスタンスに属することを表しています。
このように、has_many と belongs_to メソッドを使うことで、User モデルと Post モデル間に1対多の関係を定義することができます。
3-6. 6.ルーティング
Rails.application.routes.draw do
  devise_for :users
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  root 'posts#index'
  resources :posts
endresources :postsは、RESTfulなルーティングを生成するために使用されます。
この行は、Postモデルに関連する7つの標準的なアクション(index, show, new, create, edit, update, destroy)に対応するURLを生成します。
3-7. 7.コントローラー
rails g controller postsapp/controllers/posts_controller.rbを、以下のように編集します。
current_userとuser_signed_in?はdeviseのメソッドです。
class PostsController < ApplicationController
  before_action :move_to_index, except: [:index, :show]
  before_action :user_check, only: [:edit]
  def index
    @posts = Post.all
  end
  def show
    @post = Post.find(params[:id])
  end
  def new
    @post = Post.new
  end
  def create
    Post.create(post_params)
  end
  def edit
    @post= Post.find(params[:id])
  end
  def update
    post = Post.find(params[:id])
    post.update(post_params)
  end
  def destroy
    post = Post.find(params[:id])
    post.destroy
  end
  private
  def post_params
    params.require(:post).permit(:name, :content).merge(user_id: current_user.id)
  end
  def move_to_index
    unless user_signed_in?
      redirect_to action: :index
    end
  end
  def user_check
    unless current_user.id == Post.find(params[:id]).user_id
      redirect_to action: :index
    end
  end
endUserのコントローラーはdeviseによって自動的に作成されているため、ここでは編集しません。
3-8. 8.ビュー
1.app/views/posts/index.html.erb
<% if user_signed_in? %>
            <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
            <%= link_to "投稿する", new_post_path, class: "post" %>
        <% else %>
            <%= link_to "ログイン", new_user_session_path, class: "post" %>
            <%= link_to "新規登録", new_user_registration_path, class: "post" %>
        <% end %>
<h1>一覧</h1>
<% @posts.each do |post| %>
  <p>
      <%= post.created_at %>
      <%= post.name %>
      <% if post.content.length > 15 %>
        <%= link_to "#{post.content[0,15]}...", "/posts/#{post.id}", method: :get %>
      <% else %>
        <%= link_to "#{post.content}", "/posts/#{post.id}", method: :get %>
      <% end %>
  </p>
<% end %>2.app/views/posts/show.html.erb
<%= link_to 'トップページ', "/posts"  %>
<h1>詳細</h1>
<p><%= @post.created_at %>
<p><%= @post.name %>
<p><%= @post.content %>
<div>
  <% if user_signed_in? && current_user.id == @post.user_id %>
    <%= link_to '編集', edit_post_path(@post.id), method: :get %>
    <%= link_to '削除', post_path(@post.id), method: :delete %>
  <% end %>
</div>3.app/views/posts/new.html.erb
<%= link_to 'トップページ', "/posts" %>
<h1>新規投稿</h1>
<%= form_with(model: @post, local: true) do |form| %>
  <p>
    <%= form.label :name %><br>
    <%= form.text_field :name %>
  </p>
  <p>
    <%= form.label :content %>
    <%= form.text_area :content, rows: 5, cols: 50 %>
  </p>
  <p>
    <%= form.submit %>
  </p>
<% end %>4.app/views/posts/
4. まとめ
今回は、deviseというGemを使って簡単なWebアプリを作ってみました。
Webアプリケーション開発において、認証機能を実装することはよくあります。
RailsのGemであるdeviseは認証機能を簡単に実装できるように設計されており、さまざまな機能を提供しています。
例えば、パスワードリセットやサインアップ、サインイン、ログアウトなどの機能があります。
Javaにおいては、JSPやServletなどのWebアプリケーションフレームワークを使用して認証機能を実装することが一般的でした。
セッションを管理するためにはHttpSessionというクラスが提供されています。
HttpSessionを使用する場合、セッション情報を格納するためのデータベースやキャッシュストアを用意する必要があり、手間やコストがかかる場合があります。
一方、Railsにおいては、deviseのような認証Gemを使用することで、簡単に認証機能を実装することができます。
deviseを使用することで、ユーザー認証に必要な機能や機能をカスタマイズするための機能が提供されます。
また、deviseを使用することで、ログイン状態を保持するためのセッション情報の保存方法が自動的に実装されます。
Railsにおけるdeviseのような認証Gemの便利さは、開発者が認証機能を実装するために必要な手間やコストを削減することができる点にあります。
また、deviseを使用することで、認証機能に関連するセキュリティ上の問題を回避することができます。
これにより、開発者は認証機能について考える必要がなくなり、アプリケーションの開発に集中することができます。
今回も、ありがとうございました。






