AR삽질러

Rails 課題 - 生成メソッド、validate、viewの修正、ログイン機能 본문

Ruby/RubyOnRails-日本語

Rails 課題 - 生成メソッド、validate、viewの修正、ログイン機能

아랑팡팡 2024. 1. 3. 15:01
728x90

 

Rails 課題 - 生成メソッド、validate、viewの修正、ログイン機能

 

1. new, create 以外にオブジェクトを生成するメソッドは?その違いは?

 1) new, saveメソッド

  - 生成したインスタンスを使って何かしらの操作を行いたい場合に使う。

例)データベースの保存が成功したら、そのインスタンスの詳細パージへリダイレクトされたい場合などで、new/saveメソッドを使う。

def create
	@user = User.new(user_params)
    if @user.save
    	redirect_to @user, notice: 'User was successfully created'
    else
    	render :new
    end
end

  - saveメソッドの返り値はtrueかfalseなので、上記のコードのようにif文で保存が成功した時と失敗した時の処理を分ける事が出来る。保存が成功するとredirect_toメソッドに@userを渡して、ユーザーの詳細ページにリダイレクトする。

このように、インスタンスを使って何か操作したい場合は、new/saveメソッドを使う。

 

new/saveメソッドは、保存前や保存後にインスタンスを使って何か操作したい場合に使いう!

 

2) create

  - 生成したインスタンスを操作する必要がなくインスタンス生成と保存を同時に行っても良い場合に使用する。

user = User.create(name: "Arang", age: 20)  # インスタンス生成
user.save  # インスタンス保存

User.create(name: "Arang", age: 20) # インスタンス生成と保存

ただし、if文を使ってデータベースの保存成功と失敗の処理を分けている場合は注意が必要になる!

例)createメソッドに name: nil を渡している時、検証に引っかかってデータベースへの保存が失敗する。

 

user.rb

class User < ApplicationRecord
	validates :name, presence: true # nameが空の場合は保存しない
end

 

users_controller.rb

class UsersController < ApplicationController
	def create
    	if User.create(name: nil, age: 20)  # 保存は失敗する
        	redirect_to root_path  # 保存成功に実行したい処理
        end
        else
        	render 'new'  # 保存に失敗した時はnewに戻る           
    end
end

  - データベースへの保存が失敗したので、保存失敗の処理に記述するrender 'new'を実行したいところ、なぜか保存成功の処理が実行されルートにリダイレクトさる。

  - これは、createメソッドの返り値がデータベースの保存に失敗してもモデルのインスタンスを返す ので、if文のtrueの処理が実行されるから。

 

メソッド 種類 戻り値 用意
save Instance_Method boolean インスタンスを使って何か操作したい場合
create Class_Method Modelのインスタンス インスタンス生成と保存を同時にしても良い場合
create! Class_Method 保存失敗時は例外を発生 複数のデータ保存を行う場合

 

new データベースに保存する前にオブジェクトをメモリに生成し、オブジェクトを保存するためには、別途のsaveメソッドを使う必要がある。
create オブジェクトを生成しすぐ保存する時に使われる。有効性検査を失敗したとき、オブジェクトは保存されない。

 

3) new, create 以外にオブジェクトを生成するメソッド

メソッド 説明
find_or_create_by 与えられた属性でオブジェクトを探し、オブジェクトがない場合、新しいオブジェクトを生成する。 # 'Arang'名前がない場合、生成
user = User.find_or_create_by(name: "arang")
first_or_create 最初のオブジェクト変換したり、オブジェクトがない場合は新しいオブジェクトを生成する。 #名前が 'Arang' の最初のオブジェクトを探してない場合は、生成
user = User.first_or_create(name: "Arang").first_or_create
find_or_initialize_by 与えられた属性でオブジェクトを見つけ、存在しない場合は、新しいオブジェクトをメモリにのみ初期化(データベースには保存されない)。 #"arang"名前を持っているUserを探し、ない場合は新しいインスタンスを初期化
user = User.find_or_initalize_by(name: "Arang")
build 主に関係があるオブジェクトを生成する時に使う。
newと似ているが、主に関連関係に使用
# Userに関連されたPostを新しく生成
post = user.posts.build(title: "Rails")
create_with whereチェーンと一緒に使用され、探したり生成したりするときに特定のプロパティを設定。 #
user = User.where(name: "Arang").create_with(age: 20).first_or_create

 


2. validateについてもっと詳しく勉強する。

 - バリデーションとは、データベースに保存する前に保存する内容を検証する機能。

例)「名前やメールアドレス、パスワード」など、入力必須項目に何も入力しなかった場合、投稿ができないようにする。

他にもパスワードなどは6文字 + 特殊文字以上であるとか、すでにデータベースに存在しているメールアドレスで登録できないようにするとかデータを保存する前に検証したいときなど、そんなときに定義するのがバリデーション!
バリデーションを定義すると、データベースに保存する際、投稿された内容を検証し、保存するかどうかをチェックできるようになる。

 

例)railsの有効性検査 presence, length, format, uniqueness なと

class User < ApplicationRecord
  validates :name, presence: true
  validates :email, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
  validates :age, numericality: { only_integer: true, greater_than: 0 }
end

 

例)ユーザー定義有効性検査メゾット

class User < ApplicationRecord
    has_secure_password

    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
	#emailを小文字に変換(メールアドレスは大文字・小文字を区別しないのでため
	before_save { self.email.downcase! }

	validates :name,  presence: false, length: { maximum: 50 }
    validates :email, presence: true, uniqueness: true, length: { maximum: 50 }, format: { with: VALID_EMAIL_REGEX }
    validates :password, presence: true, length: { minimum: 6 }, if: -> { new_record? || !password.nil? }
end

has_secure_password

 - bcryptを使ってPasswordを安全にハッシュし 'password' と 'password_confirmation'  フィールドの有効性チェックを自動的に追加する。 パスワードが存在し、passwordとpassword_confirmationが一致しているかを確認する。

Email小文字に変換

 - オブジェクトが保存する前に実行される。メールアドレスをすべて小文字に変換して、データベースに一貫して保存する。

 

名前有効性検査

 - validates :name : 名前に対する有効性検査

 - presence: true : 名前の存在を検査する。

 - length: { maximum: 50 } : 名前の長さを50字に制限する。

 

email有効性検査

 - uniqueness :  同じEmailを持つユーザーの登録はできない。

 - format: { with: VALID_EMAIL_REGEX } : 与えられた 'VALID_EMAIL_REGEX' と一致することを検査する。

 

password有効性検査

 - length: { minimum: 6 } : Passwordの最小限の長さを制限する。

 - if: -> { new_record? || !password.nil? } : 新しいレコードまたっzはパスワードが既に設定されている場合にのみ、パスワードの有効性チェックを実行する。

 

2.1. presence

 - 一番多く使うヘルパーで、定義すると「空でないか」を検証する。

 - .presenceメソッドはオブジェクトが存在しemptyの状態ではない場合、そのオブジェクトを変換し、emptyの場合 nilを返す。

validates :カラム名, presence: true
# ユーザー入力値がある場合はその値を使用し、ない場合はデフォルト値を設定
name = params[:name].presence || "Default Name"

.persenceは params[:name]が空の文字列や nilの場合 nilを返し、有効な値がある場合その値を返す。

その結果、name変数には params[:name]が有効したらその値が、有効でない場合は "Default Name"を返す。

 

2.2. absence

 - presence とは逆で定義すると「空であるか」を検証する。

 - valitate :absence 検証は、主にフィールドが空である必要がある場合に使用される。 たとえば、2 つの関連フィールドのいずれかが満たされる必要がある場合、1 つのフィールドには値があり、もう 1 つのフィールドは空である必要がある場合に役立つ。

validates :カラム名, absence: true
class UserModel < ApplicationRecord
	validates :attribute_name, absence: true
end

:attribute_nameは検証するモデルの属性で、absence: trueは属性が開いている時に有効になる。

 

2.3. uniqueness 

 - 値が一意(unique )であり重複していないかを検証する。

 - メールアドレスなど重複しては困る時に使う。

validates: カラム名, uniquencess: true
class UserModel < ApplicationRecord
	validates :email, uniqueness: true
end

このコードでは、validates:email、uniqueness:trueはemailフィールドの値がデータベース内で唯一であることを示す。


3. ログイン機能

users_controller.rb

class UsersController < ApplicationController

    before_action :correct_user, only: [:show, :edit, :update, :destroy]

    def index
        @users = User.all
    end

    def show
        @user = User.find_by(id: params[:id])
        redirect_to(root_url, notice: "User not found") if @user.nil?
    end      

    def new
        @user = User.new
    end

    def create
        @user = User.new(user_param)
        if @user.save
            redirect_to user_path(@user), notice: "User successfully created"
        else
            Rails.logger.info(@user.errors.inspect)
            render :new
        end
    end

    def edit
        @user = User.find(params[:id])
    end

    def update
        @user = User.find(params[:id])
        if @user.update(user_param)
            redirect_to user_path(@user), notice: 'ユーザー情報が更新されました。'
        else
            flash.now[:alert] = @user.errors.full_messages
            render :edit, status: :unprocessable_entity
        end
    end

    def destroy
        @user = User.find(params[:id])
        @user.destroy
        redirect_to root_path, notice: 'ユーザーが削除されました。'
    end    

    private
        def user_param
            params.require(:user).permit(:name, :email, :password, :password_confirmation)
        end

        def correct_user
            @user = User.find_by(id: params[:id])
            unless @user && @user == current_user
            flash[:alert] = 'ユーザー情報に接近できません。。Loginしてください!'
            redirect_to root_path
        end
    end
end

 

実装した機能Users

 1) new, save, create == 会員登録

 2) show == ユーザーの情報

 3) edit, update == ユーザー情報更新

 4) destroy == ユーザー削除

 5) index == ユーザーList


4. viewの修正

 

 


https://github.com/designAR/rails_tutorial_to_do_list/tree/login_%2301

 

GitHub - designAR/rails_tutorial_to_do_list

Contribute to designAR/rails_tutorial_to_do_list development by creating an account on GitHub.

github.com

 

 

 

728x90
반응형
LIST