Ruby on Rails5 道場コース III

2. image_nameカラムを追加しよう
画像を保存するために、usersテーブルにimage_nameカラムを追加しましょう。
usersテーブルにimage_nameカラムを追加してください。データ型はstringとしてください。

def change
add_column :テーブル名, :カラム名, :データ型
end

1マイグレーションファイルを作成
usersテーブルに画像名を保存するために、マイグレーションファイルを作成しましょう。
ターミナル
rails g migrationコマンドを用いて、
add_image_name_to_users
というファイル名で、マイグレーションファイルを作成してください。
rails g migration add_image_name_to_users

2マイグレーションファイル編集
class AddImageNameToUsers < ActiveRecord::Migration[5.0] def change add_column :users, :image_name, :string end end 3マイグレーションファイルをデータベースに反映 rails db:migrate 3. 初期画像を設定しよう createアクションで、Userインスタンスを作成するときにimage_nameカラムの値が設定されるようにしてください。 (※ newメソッドの引数を追加します) users_controller.rb def create @user = User.new( name: params[:name], email: params[:email], image_name: "default_user.jpg" ) プロフィール画像を表示 show.html.erb

“>

4. 画像編集機能を作ろう
画像編集機能を作ろう
ユーザー編集ページから画像をアップロードできるようにしましょう。
画像を保存する時はファイル名はデータベースに保存し、画像データはpublicフォルダ内に保存するようにします。

ユーザー編集ページで、「保存」ボタンが押された時に画像データが送信されるようにしてください。
ヒント
ヒント
画像用のフォームを作成します。
以下のように、inputタグにtype=”file”を指定します。

form_tagメソッドに「{multipart: true}」を追加することで、画像を送信できます。
以下のように指定しましょう。
<%= form_tag("送信先のURL", {multipart: true}) %>

usersコントローラのupdateアクションで画像データを受け取り、画像データが存在する時にだけ画像が保存されるようにしてください。
ただし、画像のファイル名はデータベースに、画像データはpublic/user_imagesフォルダに保存してください。
また、画像のファイル名は「1.jpg」のように「ユーザーのid.jpg」となるようにしてください。
ヒント
画像データをpublic/imagesフォルダに保存しましょう。
以下のように、binwriteメソッドとreadメソッドを用います。
File.binwrite(“public/user_images/#{画像名}”, 画像データ.read)

https://prog-8.com/rails5/study/7/6#
https://prog-8.com/rails5/study/7/8#/25

def update
@user = User.find_by(id: params[:id])
@user.name = params[:name]
@user.email = params[:email]

if params[:image]
@user.image_name = “#{@user.id}.jpg”
image = params[:image]
File.binwrite(“public/user_images/#{@user.image_name}”, image.read)
end

if @user.save
flash[:notice] = “ユーザー情報を編集しました”
redirect_to(“/users/#{@user.id}”)
else
render(“users/edit”)
end
end

5. パスワードカラムを追加しよう

https://prog-8.com/rails5/study/8/3#

■ ターミナルで以下のコマンドを実行してください
rails g migration add_password_to_users
■ マイグレーションファイル編集後に、ターミナルで以下のコマンドを実行してください
rails db:migrate

20170612014736_add_password_to_users.rb
class AddPasswordToUsers < ActiveRecord::Migration[5.0] def change add_column :users, :password, :string end end ■ コンソールで以下のコードを実行してください user = User.find_by(id: 1) user.password = "好きなパスワード" user.save user.rb class User < ApplicationRecord validates :name, {presence: true} validates :email, {presence: true, uniqueness: true} validates :password, {presence: true} end 6. ログインフォームを作成しよう ・ 対応するアクションはusersコントローラのloginアクションとなるようにしてください。 ・ post URL => コントローラ名#アクション名となるようにしてください。

get “login” => “users#login_form”

def login
end

  • <%= link_to("ログイン", "/login") %>
  • 7. ログイン処理を追加しよう
    ユーザーが存在する場合、以下の処理を行ってください。
    ・フォームに入力されたデータからユーザーを特定し、そのユーザーが存在する場合、session[:user_id]にユーザーのidを代入してください。
    ・ログイン後、
    ログインしました
    というフラッシュが表示されるようにしてください。
    ・ログイン後、投稿一覧ページにリダイレクトされるようにしてください。

    ユーザーが存在しない場合の処理を作りましょう。
    ユーザーが存在しない場合には、ログインページが再表示されるようにしてください。
    ログインしている場合には、ヘッダーに「ログイン中のユーザーのid」を表示しましょう。

    ログイン中のユーザーがいる場合には、ヘッダーに「現在ログインしているユーザーのid: 1」のように、ログイン中のユーザーのidを表示してください。
    現在ログインしているユーザーのid:

    post “login” => “users#login”

    def login_form
    end

    def login
    @user = User.find_by(email: params[:email], password: params[:password])
    if @user
    session[:user_id] = @user.id
    flash[:notice] = “ログインしました”
    redirect_to(“/posts/index”)
    else
    render(“users/login_form”)
    end
    end

    <% if session[:user_id] %>

  • 現在ログインしているユーザーのid:
    <%= session[:user_id] %>
  • <% end %>

    8. ユーザーが存在しない場合の処理
    ログイン処理で、ユーザーが存在しなかった場合の処理を完成させましょう。
    ログインに失敗した場合に、エラーメッセージを表示するようにしてください。
    ログインに失敗した場合にメールアドレスとパスワードのフォームに初期値が入るようにしてください。

    users_controller.rb
    def login
    @user = User.find_by(email: params[:email], password: params[:password])
    if @user
    session[:user_id] = @user.id
    flash[:notice] = “ログインしました”
    redirect_to(“/posts/index”)
    else
    @error_message = “メールアドレスまたはパスワードが間違っています”
    @email = params[:email]
    @password = params[:password]
    render(“users/login_form”)
    end
    end

    login_form.html.erb


    <% if @error_message %>


    <%= @error_message %>

    <% end %>

    <%= form_tag("/login") do %>

    メールアドレス




    <% end %>

    9. ユーザー登録時にログイン状態にしよう
    ユーザー登録時にもログイン状態となるようにしていきましょう。
    まずは、ユーザー登録ページでもログインページと同じようにパスワードの入力欄を追加しましょう。
    メールアドレス入力欄の下に以下のHTMLを貼り付けて、パスワード用の入力欄を追加してください。
    ・ユーザー登録に失敗した場合には、パスワードの入力欄に初期値が入るようにしてください。
    ・usersコントローラのcreateアクションで、入力されたパスワードを取得し保存してください。
    ・ユーザーの登録に成功した場合、登録されたユーザーがログインするようにしてください。

    new.html.erb
    <%= form_tag("/users/create") do %>

    ユーザー名


    <% end %>

    users_controller.rb
    def create
    @user = User.new(
    name: params[:name],
    email: params[:email],
    image_name: “default_user.jpg”,
    password: params[:password]
    )
    if @user.save
    session[:user_id] = @user.id
    flash[:notice] = “ユーザー登録が完了しました”
    redirect_to(“/users/#{@user.id}”)
    else
    render(“users/new”)
    end
    end

    10. ログアウト機能を作ろう
    ログアウト機能を作成してみましょう。
    ・ヘッダーに「ログアウト」リンクを用意し、リンクがクリックされた時にユーザーがログアウトできるようにしてください。「ログアウト」リンクのURLは/logoutとしてください。
    ただし、アクションはusersコントローラに定義してください。
    ・ログアウト後に、
    ログアウトしました
    というフラッシュを表示してください。
    ・ログアウト後は、ログインページにリダレクトしてください。

    ログアウトするためには、
    session[:user_id] を nil にします。

    ログアウト機能ができたら、ログインしている状態としていない状態でヘッダーに表示する内容を変えてみましょう。

    routes.rb
    post “logout” => “users#logout”

    users_controller.rb
    def logout
    session[:user_id] = nil
    flash[:notice] = “ログアウトしました”
    redirect_to(“/login”)
    end

    application.html.erb

      <% if session[:user_id] %>

    • 現在ログインしているユーザーのid:
      <%= session[:user_id] %>
    • <%= link_to("投稿一覧", "/posts/index") %>
    • <%= link_to("新規投稿", "/posts/new") %>
    • <%= link_to("ユーザー一覧", "/users/index") %>

    • <%= link_to("ログアウト", "/logout", {method: :post}) %>
    • <% else %>

    • <%= link_to("TweetAppとは", "/about") %>
    • <%= link_to("新規登録", "/signup") %>
    • <%= link_to("ログイン", "/login") %>
    • <% end %>

    11. ヘッダーにユーザー名を表示しよう
    ヘッダーに現在ユーザーのidが表示されていますが、その代わりにログイン中のユーザーの名前を表示してください。
    また、そのユーザーの詳細ページへのリンクとなるようにしてください。

    ヒント
    共通処理は application_controller内に記述します。
    また、 before_action を定義することで、事前処理を行うことができます。
    以下のように記述します。
    before_action :メソッド名

    def メソッド名
    全アクションで共通する処理
    end

    before_action
    before_action
    各コントローラの全アクションで共通する処理がある場合には、before_actionを使うと便利です。before_actionを用いることで、アクションが呼び出される際に必ずbefore_actionの処理が実行されます。
    これにより、全アクションで共通する処理を1箇所にまとめることができます。

    application_controller.rb
    class ApplicationController < ActionController::Base before_action :set_current_user def set_current_user @current_user = User.find_by(id: session[:user_id]) end end 12. ログインしていない場合のアクセス制限 ログインしていない場合にアクセスできないページを作成していきましょう。 ログインしていないユーザーが以下のアクションにアクセスした場合には、ログインページへリダイレクトするようにしてください。 ・postsコントローラの全アクション ・usersコントローラのindex, show, edit, updateアクション また、 ログインが必要です というフラッシュを表示してください。 ヒント before_actionは限定して適用することができます。 onlyを用いることで、指定したアクションにだけbefore_actionを適用させることができます。 before_action :メソッド名, {only: [:アクション名, :アクション名, ... ]} posts_controller.rb class PostsController < ApplicationController before_action :authenticate_user users_controller.rb class UsersController < ApplicationController before_action :authenticate_user, {only: [:index, :show, :edit, :update]} application_controller.rb def authenticate_user if @current_user == nil flash[:notice] = "ログインが必要です" redirect_to("/login") end end 13. ログインしている場合のアクセス制限 ログインしている場合にアクセスできないページを作っていきましょう。 ログイン中のユーザーが以下のURLにアクセスした場合には、投稿一覧ページにリダイレクトしてください。 ・get /signup ・get /login ・get / (localhost:3000) ・post /users/create ・post /login また、 すでにログインしています というフラッシュを表示してください。 posts_controller.rb class PostsController < ApplicationController before_action :authenticate_user users_controller.rb class UsersController < ApplicationController before_action :authenticate_user, {only: [:index, :show, :edit, :update]} before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]} home_controller.rb class HomeController < ApplicationController before_action :forbid_login_user, {only: [:top]} 14. 自分の情報のみ編集できるようにしよう ログインしているユーザーの情報のみ編集できるようにしていきましょう。 まずは、ユーザー詳細ページの「編集」リンクは自分の詳細ページの時にだけ表示するようにしましょう。 ユーザー詳細ページで、詳細ページのユーザーとログインしているユーザーが一致した場合のみ「編集」リンクが表示されるようにしてください。 次に、URLを直接入力した時にもアクセス制限がかかるようにしましょう。 ログインしているユーザーが他のユーザーの編集ページ、ユーザー情報更新時のURLにアクセスした場合には、投稿一覧ページにリダイレクトしてください。 また、 権限がありません というフラッシュを表示してください。 show.html.erb <% if @user.id == @current_user.id %>
    <%= link_to("編集", "/users/#{@user.id}/edit")%>

    users_controller.rb
    def ensure_correct_user
    if params[:id].to_i != @current_user.id
    flash[:notice] = “権限がありません”
    redirect_to(“/posts/index”)
    end
    end

    シェアする

    • このエントリーをはてなブックマークに追加

    フォローする