パスワードカラムを追加
rails g migration add_password_to_users
rails generate migration user image_name:string
違いは何だろう?
カラムのデータ型を指定
class AddPasswordToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :password, :string
end
end
1番目のユーザーのパスワードを変える
tweet_app $ rails console
Loading development environment (Rails 5.0.3)
[1] pry(main)> user = User.first
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<User:0x0000555f56c6f010
id: 1,
name: "あ",
email: "hogehoge",
created_at: Wed, 11 May 2022 14:53:09 JST +09:00,
updated_at: Wed, 11 May 2022 16:36:05 JST +09:00,
image_name: "1.jpg",
password: nil>
[2] pry(main)> user.password = hogehoge
NameError: undefined local variable or method `hogehoge' for main:Object
from (pry):2:in `__pry__'
[3] pry(main)> user.password = "hogehoge"
=> "hogehoge"
[4] pry(main)> user.save
(0.1ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? AND ("users"."id" != ?) LIMIT ? [["email", "hogehoge"], ["id", 1], ["LIMIT", 1]]
SQL (1.4ms) UPDATE "users" SET "updated_at" = ?, "password" = ? WHERE "users"."id" = ? [["updated_at", "2022-05-12 05:03:07.402656"], ["password", "hogehoge"], ["id", 1]]
(12.6ms) commit transaction
=> true
パスワード属性にバリデーションをかける
class User < ApplicationRecord
.
.
.
validates :password, {presence: true}
end
ログインフォームを作成する
まずlocalhost:3000/login
にアクセス
Routing Error
No route matches [GET] "/login"
ルーティングを設定
routes.rb
Rails.application.routes.draw do
get "/login" => "users#login"
.
.
.
end
行き先のコントローラにlogin
アクションを設定する
users_controller.rb
class UsersController < ApplicationController
.
.
.
def login
end
end
自動的にアクション名のファイルを探すのでファイルを作成する
login.html.erb
内容を貼り付け
これで表示成功!
ヘッダーにログイン
を表示させる
application.html.erbにリンクを書く。
application.html
<li>
<%= link_to("ログイン", "/login") %>
</li>
ログイン処理を追加
フォームから送信されたメールアドレスとパスワードからユーザーを特定し、ユーザーが存在すればそのユーザーの情報をブラウザに保存するようにしましょう。
まずボタンで送信できるようにしよう。
login.html
<%= form_tag("/login") do %>
<div class="form users-form">
<div class="form-body">
<p>メールアドレス</p>
<input>
<p>パスワード</p>
<input type="password">
<input type="submit" value="ログイン">
</div>
</div>
<% end %>
<%= %>
をつけなければ中身が表示されない
これで送信してみよう。
Routing Error
No route matches [POST] "/login"
ルーティングが設定されていなかった。
routes.rb
Rails.application.routes.draw do
get "/login" => "users#login"
post "/login" => "users#login"
.
.
.
end
確かform_tag
は基本的にPOST
のHTTPメソッドを使うはず...
だがらgetのルーティングには行かないと思う。
送信ボタンを押したがloginのページに行ってしまう。 どういうことだろうか?
## loginアクションを書いてみる
user_controller.rb
class UsersController < ApplicationController
.
.
.
def login
@user = User.find_by(
email: params[:email],
password: params[:password])
if @user
session[:user_id] = @user.id
flash[:notice] = "ログインしました"
redirect_to("/users/index")
else
render("index")
end
end
end
送信されて作動してくれるのか送信ボタンを押してみた。
NoMethodError in Users#login
Showing /home/progate/tweet_app/app/views/users/index.html.erb where line #4 raised:
undefined method `each' for nil:NilClass
インスタンス変数が空だということはわかった。
解決
users_controller.rb
.
.
.
def login
.
.
.
else
render("login")
end
end
end
エラーが消え成功した。
ヘッダーにユーザーidを表示させる
application.html.erbに書く
application.html
<ul class="header-menus">
<li>
<%= "現在ログインしているユーザーのid:#{session[:user_id]}" %>
</li>
.
.
.
ログインしていない場合でも、ヘッダーにユーザーのidが表示されています。
・ログアウトをした後も表示される
わからなかった。
if session[:user_id]で判断させる
session[:user_id]で判断させることによってログイン中か否かを判断させることができる。