質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Q&A

解決済

1回答

3029閲覧

Ruby on Rails6 [devise] 自分以外のユーザーのプロフィールを編集できないようにしたい

退会済みユーザー

退会済みユーザー

総合スコア0

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

0グッド

1クリップ

投稿2020/07/29 22:04

編集2020/07/29 22:21

実現したいこと

・deviseでユーザー認証機能を導入したい
・その過程で、自分以外のユーザーのプロフィールを編集できないようにしたい
・ユーザーのプロフィールページに置かれたリンクをクリックすることで、プロフィールの編集ページに移動させたい

発生している問題・エラーメッセージ

上記の機能をprotectedメソッドとして定義してみたのですが、プロフィールの編集のリンクを押したところ、編集ページ(registrations#edit)に入れませんでした。

ブラウザには下記のエラーが表示されています。

ActiveRecord::RecordNotFound in Users::RegistrationsController#edit Couldn't find User without an ID # edit, updateアクションを現在のユーザーのみに限定する def correct_user @user = User.find(params[:id]) redirect_to(root_url) unless @user == current_user end

該当のソースコード

Railstutorialを参考にprotectedメソッドにcorrect_userを定義しました。
ただ、これが原因でエラーが出ているようです。

Ruby

1# frozen_string_literal: true 2 3class Users::RegistrationsController < Devise::RegistrationsController 4 before_action :authenticate_user!, only: [:edit, :update, :destroy] 5 before_action :correct_user, only: [:edit, :update] 6 7 def new 8 super 9 end 10 11 def create 12 super 13 end 14 15 def edit 16 super 17 end 18 19 def update 20 super 21 end 22 23 def destroy 24 super 25 end 26 27 protected 28 29 # edit, updateアクションを現在のユーザーのみに限定する 30 def correct_user 31 @user = User.find(params[:id]) 32 redirect_to root_path unless @user == current_user 33 end 34 35end 36 37

該当のview

こちらはdeviseと関係なく作成したユーザーのプロフィールページ(users#show)です。
「プロフィールの編集」リンクを押して、プロフィール編集画面に移動する際に上記のエラーがでました。
このページは正しく表示されています。

Ruby

1<% provide(:title, @user.name) %> 2 3<h3>プロフィール</h3> 4<p>名前 : <%= @user.name %></p> 5<p>メールアドレス: <%= @user.email %></p> 6 7<%= link_to 'プロフィールの編集', edit_user_registration_path(@user) %>

routes.rb

Ruby

1Rails.application.routes.draw do 2 root 'static_pages#home' 3 get '/help', to:'static_pages#help' 4 get '/about', to:'static_pages#about' 5 get '/contact', to:'static_pages#contact' 6 devise_for :users, :controllers => { 7 :confirmations => 'users/confirmations', 8 :registrations => 'users/registrations', 9 :sessions => 'users/sessions' 10 } 11 devise_scope :user do 12 get "sign_in", to:"users/sessions#new" 13 delete "sign_out", to:"users/sessions#destroy" 14 end 15 resources :users, only: [:index, :show] 16end 17

試したこと

Rspecでregistrations_controllerのテストをしました。
そのテストはパスするのですが、そもそも正しいテストを書けているか自信がありません。

念のため、以下にテスト内容とテストデータ(FactoryBot)を記載します。

Ruby

1require 'rails_helper' 2 3describe Users::RegistrationsController, type: :controller do 4 let(:user) { create(:user) } 5 let(:other_user) { create(:other_user) } 6 7 # ユーザー情報編集ページの表示をテスト 8 describe 'GET #edit' do 9 # ログインしている場合 10 context 'with logged in' do 11 # edit(ユーザー情報編集)ページの検証 12 it 'responds successfully' do 13 @request.env["devise.mapping"] = Devise.mappings[:user] 14 sign_in user 15 get :edit, params: { id: user.id } 16 expect(response).to have_http_status "200" 17 expect(response).to render_template :edit 18 end 19 end 20 # ログインしていない場合 21 context 'without logged in' do 22 # edit(ユーザー情報編集)ページの代わりにsign_in(ログイン)ページを返すか検証 23 it 'redirect to new_session_path' do 24 @request.env["devise.mapping"] = Devise.mappings[:user] 25 get :edit, params: { id: user.id } 26 expect(response).to have_http_status "302" 27 expect(response).to redirect_to new_user_session_path 28 end 29 end 30 # 他のユーザーでログインしている場合 31 context 'with logged in as other user' do 32 # ルートにリダイレクトされるか検証 33 it 'redirect to root_path' do 34 @request.env["devise.mapping"] = Devise.mappings[:user] 35 sign_in other_user 36 get :edit, params: { id: user.id } 37 expect(response).to have_http_status "302" 38 expect(response).to redirect_to root_path 39 end 40 end 41 end 42 43end

Ruby

1FactoryBot.define do 2 3 factory :user, class: User do 4 name { 'foo' } 5 email { 'foo@test.com' } 6 password { 'foo123' } 7 password_confirmation { 'foo123' } 8 confirmed_at { Date.today } 9 end 10 11 factory :other_user, class: User do 12 name { 'bar' } 13 email { 'bar@test.com' } 14 password { 'bar123' } 15 password_confirmation { 'bar123' } 16 confirmed_at { Date.today } 17 end 18 19end

確認したこと

correct_userがなければ編集ページに移動できることは確認しており、その際URLにはユーザーのIDが記載されていました。そのため、IDが見つからないからユーザーを検索できないというエラーの原因がわかりませんでした。

1日悩んでわからなかったので、どなたか原因を教えていただけないでしょうか。
質問に不備がある場合は遠慮なく伝えていただけると幸いです。

どうぞよろしくお願いします。

補足情報(FW/ツールのバージョンなど)

ruby 2.7.1
Rails 6.0.3.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/07/29 22:22

deviseが生成したルーティングを書いていただけますか?
退会済みユーザー

退会済みユーザー

2020/07/29 22:30

質問の意図が把握できず申し訳ないのですが、ターミナルで「rails routes」と打って出てくるルーティングのことでしょうか? もしそれだとしたら、下記のとおりです。(整形ができず見辛くてすみません) new_user_session GET /users/sign_in(.:format) users/sessions#new user_session POST /users/sign_in(.:format) users/sessions#create destroy_user_session DELETE /users/sign_out(.:format) users/sessions#destroy new_user_password GET /users/password/new(.:format) devise/passwords#new edit_user_password GET /users/password/edit(.:format) devise/passwords#edit user_password PATCH /users/password(.:format) devise/passwords#update PUT /users/password(.:format) devise/passwords#update POST /users/password(.:format) devise/passwords#create cancel_user_registration GET /users/cancel(.:format) users/registrations#cancel new_user_registration GET /users/sign_up(.:format) users/registrations#new edit_user_registration GET /users/edit(.:format) users/registrations#edit user_registration PATCH /users(.:format) users/registrations#update PUT /users(.:format) users/registrations#update DELETE /users(.:format) users/registrations#destroy POST /users(.:format) users/registrations#create new_user_confirmation GET /users/confirmation/new(.:format) users/confirmations#new user_confirmation GET /users/confirmation(.:format) users/confirmations#show POST /users/confirmation(.:format) users/confirmations#create sign_in GET /sign_in(.:format) users/sessions#new sign_out DELETE /sign_out(.:format) users/sessions#destroy users GET /users(.:format) users#index user GET /users/:id(.:format) users#show
guest

回答1

0

ベストアンサー

edit_user_registration GET /users/edit(.:format) users/registrations#edit

とあるように、もともとこのコントローラーはid引数を取りません。つまり、何もしなくても現在ログインしているユーザー専用です。

投稿2020/07/29 22:35

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/07/29 22:55

ご回答ありがとうございます!謎が解けてスッキリしました! つまり、correct_userを定義する必要はなく、自動的にログインユーザーのプロフィールしか編集できないように設計されているということなんですね。 この問題に関係がありそうな記事がヒットしなかたことにも納得しました笑 ご丁寧に教えていただきましてありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問