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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby on Rails 5

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

Q&A

3回答

610閲覧

エラー文の・no route matchs{:action=>"edit", :controller=>"users", :id=>nil} を解決するためのアドバイスが知りたい。

NEMOTOSHOTA

総合スコア32

Ruby on Rails 5

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

0グッド

0クリップ

投稿2020/02/08 14:05

編集2020/02/09 09:37

現状

ログイン後、自分の情報(メアド、名前、パスワードなど)を変更するページを作成していた。
ある程度作成し終わり、挙動を確かめようとrails sでサーバーを立てて作成したメールアドレス、パスワードでログインし、自身の情報を編集するページに移動して編集をした。編集し終わり、更新ボタンを押したところ下記のエラーが出ました。

イメージ説明

したいこと

ユーザー情報を更新できるようにしたい。

原因・考察

調べた限り、下記が原因かと思います。
・no route matchs{:action=>"edit", :controller=>"users", :id=>nil}
→どのuserをeditしたいかを指定するためのid(インスタンス変数はuser)が指定されていない。
→no route matchs でルートがない。

・missing required keys: [:id]
→必須のキーがない。

・current_userの値がnilになっている。

app/models/user.rbをみたところ、update_attributesメソッド他、@userの情報を受け渡しするようなコードが一行も書かれていなかったことに気づく。
image.png
→しかし、チュートリアル7章→app/models/user.rbのコードサンプルをみてもユーザー情報の更新について言及しているコードは見当たらない。

→route.rbでの指定がおかしい?ルートの指定がないのがおかしい?

やったこと

app/controllers/users_controller.rbにeditアクションを追加。

class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new @user = User.new end def create @user = User.new(user_params) if @user.save log_in @user flash[:success] = "Welcome to the Sample App!" redirect_to @user else render 'new' end end def edit #ユーザー情報編集のeditアクション。 app/views/users/edit.html.erb @user = User.find(params[:id]) end def update #ユーザー情報を更新する @user = User.find(params[:id]) if @user.update_attributes(user_params) flash[:success] = "Profile updated" redirect_to @user else render 'edit' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end # ログイン済みユーザーかどうか確認 def logged_in_user unless logged_in? flash[:danger] = "Please log in." redirect_to login_url end end end

app/views/users/edit.html.erbに入力フォームを追加。

<% provide(:title, "Edit user") %> <h1>Update your profile</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <%= form_for(@user) do |f| %> <%= render 'shared/error_messages' %> <%= f.label :name %> <%= f.text_field :name, class: 'form-control' %> <%= f.label :email %> <%= f.email_field :email, class: 'form-control' %> <%= f.label :password %> <%= f.password_field :password, class: 'form-control' %> <%= f.label :password_confirmation, "Confirmation" %> <%= f.password_field :password_confirmation, class: 'form-control' %> <%= f.submit "Save changes", class: "btn btn-primary" %> <% end %> </div> </div>

・app/views/layouts/_header.html.erbにリンクを追加。

<%= link_to "Settings", edit_user_path(current_user) %>

今回動かしたいのはcontroller/users_controller.rbの editアクションなので、rake routesで正しいルートを確認し、route.rb内に以下を追加。
get '/users/:id/edit', to: 'users#edit'

Rails.application.routes.draw do # ログイン、アカウント編集後、任意のページに推移させるための記述 devise_for :users, :controllers => { :omniauth_callbacks => 'users/omniauth_callbacks', #facebookログイン :registrations => 'users/registrations', #登録時 :sessions => 'users/sessions', :passwords => 'users/passwords' } resources :users get 'users/show' get 'comments/index' root 'static_pages#home' # => root_path get '/users/:id/edit', to: 'users#edit' get '/help', to: 'static_pages#help' get '/about', to: 'static_pages#about' get '/contact', to: 'static_pages#contact' get '/signup', to: 'users#new' # => contact_path # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html #root 'application#hello' end

結果

@userの部分をUser.firstにしたところ、正常に動きました。
ただ、どのユーザーでも動いて欲しいので@userにしたところ同じエラー文が表示されました。

助言、よろしくお願いします。

【追記】

bundle exec rails routesの結果

static_pages_controller.rbの内容

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

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

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

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

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

siruku6

2020/02/08 20:54

以下の二つを掲載すると回答が付きやすくなると思います ①$ bundle exec rails routes を実行した結果 ②staticpagesコントローラーファイルの内容 これらがないと、原因を想像することが難しいです ---- 別件ですが、 resources :users が既に存在しているので、 get 'users/show' get '/users/:id/edit', to: 'users#edit' は削除しても大丈夫なはずです
NEMOTOSHOTA

2020/02/09 00:12

回答ありがとうございます、 ①$ bundle exec rails routes を実行した結果 ②staticpagesコントローラーファイルの内容 上記を追加しましたのでアドバイスをしていただければと思います、よろしくお願いします。
siruku6

2020/02/09 00:55 編集

ありがとうございます。 ちなみにですが、current_user が nil になっているのってどうやって判明しましたか? ぱっと見たところ、 <%= link_to "Settings", edit_user_path(current_user) %> これで上手くいきそうなのですが。
NEMOTOSHOTA

2020/02/09 01:04 編集

元々、<%= link_to "Settings", edit_user_path(current_user) %>にしていたのですが、これで同じエラーが出ていたので、そこからcurrent_userの値がnilになっている、と判断しました。そして、@userに変更して<%= link_to "Settings", edit_user_path(@user) %>に変更した、という経緯があります。
siruku6

2020/02/09 01:07

なるほど!
NEMOTOSHOTA

2020/02/09 01:22 編集

そして、@userの値をUser.firstと直接指定してあげると、うまく動きます。
Mugheart

2020/02/09 08:48

バグだとかエラーだとか以前の話なんだけど、そもそもDeviseでUserモデル管理してるはずなのにそれとは別に独自のコントローラ作成してDevise経由せずにUserレコードに変更を加えちゃってるのがまずいと思う。
Mugheart

2020/02/09 08:51

Deviseのドキュメントを再度じっくり読み直したり、「Devise Controller カスタマイズ」でググって本来のアプローチを確認してみると間違いに気付けるかもしれないです。
Mugheart

2020/02/09 08:53

一応回答に書いておきます。
guest

回答3

0

app/controllers/users_cpntroller.rb

そもそもこれは存在してはいけないコントローラです。(加えてtypoもしてます。)
独自でコントローラをカスタマイズしたい場合はそれ専用のファイルを作成してください。
Configuring controllers

bash

$ rails generate devise:controllers [scope]

```rb

class Users::SessionsController < Devise::SessionsController

GET /resource/sign_in

def new

super

end

...
end

Deviseは普段触らないので細かいことまではわかりませんが、Deviseを経由せずに勝手にUserレコードに変更を加えてるのが意図しない動作をしている原因なのでは?

投稿2020/02/09 08:59

編集2020/02/09 09:01
Mugheart

総合スコア2349

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

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

0

追記修正依頼のやり取りで判明しましたが、原因は恐らく、サインイン中のユーザー情報を編集したことによる自動ログアウトだと思われます。

対策を調べてみたのですが、みんなやってることが若干違うので、参考情報の掲載を一旦してみます。色々試してみていただけるとよいと思います。

で、@user ではなく やはり current_user を引数として渡すのが自然だと思います。


参考情報

deviseが勝手にログアウトする現象の対処方法
今回と同じ現象ですね。

他にも色々記事があって、みんなやっていることが若干違うようです。。。

deviseでログイン状態が維持できない際の対応

パスワード変更時にログアウトしてしまう場合の対処法

投稿2020/02/09 01:10

siruku6

総合スコア1382

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

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

0

redirect_to @user を render actiion: :show にしてください

投稿2020/02/08 21:34

winterboum

総合スコア23567

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

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

NEMOTOSHOTA

2020/02/09 01:03 編集

回答ありがとうございます。 users_controller.rbの中のredirect_to @user を render actiion: :show にしましたが同じエラーになりました。 追記でrails routesの内容とstatic_pages_cotroller.rbの内容を追記しましたのでご確認ください。
siruku6

2020/02/09 01:01

そういえば、今回の件には関係ないかもしれないのですが、ログイン中のユーザーインスタンスのDB情報を編集するとログアウトしてしまうバグに過去出くわしたことがあるような気もします。 もしかしたら、その現象が発生するのは変更対象がパスワードの時だけだったかもしれませんが、ちょっと調べてみます。 その際は確か、 bypass signin だったか、そんな名前のメソッドを使ったような気がします。
NEMOTOSHOTA

2020/02/09 01:17

URlありがとうございます。 URLをみてみますと、今回私が直面しているエラー文no route matchs{:action=>"edit", :controller=>"users", :id=>nil}とは異なるエラーの対応だと思うのですが、bypassを使って試してみます。
siruku6

2020/02/09 01:26 編集

error文は確かに違いますが、どちらも、ユーザー情報を書き換えたことによってログアウトしている(current_userがnilになっている)という共通の現象が発生しており、それがerror原因になっています。 なので、自動でログアウトされてしまうことを防げれば解決すると思います。 実際に動くコードを掲載できないのは申し訳ないのですが、お試しください....
NEMOTOSHOTA

2020/02/09 01:30

なるほど、ありがとうございます。 とんでもございません、アドバイスをいただいただけありがたいです。 進展がありましたらこちらにコメントいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問