konchanxxx / menta

MENTAのタスク管理用リポジトリ
0 stars 0 forks source link

データベースを発見できない #49

Closed RYUTAONO0929 closed 5 years ago

RYUTAONO0929 commented 5 years ago

概要

現場rails p159のようにユーザーの削除、編集機能を追加したのですが、ActiveRecord::RecordNotFound in Admin::UsersController#showと表示されます。 ルーティングの問題でしょうか?

実現したいこと

railsでデータの編集・削除機能をついかしたいです。

困っていること

railsがデータを認識しない。 users_controller.rbのタイポはありませんでした。

困っていることがバグの場合は事象やログ、エラーメッセージをできるだけそのまま(抜粋などしない)下記に記載してください。

ActiveRecord::RecordNotFound in Admin::UsersController#show Couldn't find User with 'id'=6

17 18 19 20 21 22 def show @user = User.find(params[:id]) end def index

スクリーンショット (12)

解決するために行ったこと

ググってみたのですが、何が間違っているのか分かりませんでした。 たぶんrailsがデータ(postgresql)を認識していないのでは。。。

問題となっている箇所の予想

taskleaf/app/dbに問題があるのでしょうか?)

問題となっているアプリケーションのGitHub URL

konchanxxx commented 5 years ago
Couldn't find User with 'id'=6

のところはどう解釈した感じでしょうか? dbに接続できない場合はconnectionのエラーとかになるかなと思います。

$ bundle exec rails c
$ User.find(6)

とかでユーザーが取得できるかどうか確認できます:bow:

ググってみたのですが、何が間違っているのか分かりませんでした。

なんだか解決するためにとりあえずググって似たような記事を試してみるみたいな悪い習慣が身についているのかなと思っており、ちゃんとデバッグ(バグを見つけること)できるようになった方が良いかなと思いました。 プロを目指す人のためのRuby入門binding.pryを利用するところとかを再読した方が良いと思います:bow:

konchanxxx commented 5 years ago

あと気になったのはタイトルがデータベースを発見できないとなっているのに困っていることがrailsがデータを認識しないとなっている点とかでしょうか。 データとデータベースの違いを明確に使い分けるべきだと思います。

たぶんrailsがデータ(postgresql)

とかもデータとデータベースが混同していそうです。

一つ一つの単語の意味を理解して正しいものを使えるようにしていくことが重要かなと思います:bow:

RYUTAONO0929 commented 5 years ago

一日置いて、もう一度rails sでサーバーを起動したところ解決しました。 ご指摘有難うございます。 $ bundle exec rails c $ User.find(6) の結果は以下のようなものです。 ‘‘‘ ryutaono@DESKTOP-G6D20US:~/taskleaf$ bundle exec rails c Running via Spring preloader in process 1441 /home/ryutaono/taskleaf/vendor/bundle/ruby/2.5.0/gems/spring-2.0.2/lib/spring/application.rb:185: warning: Insecure world writable dir /mnt/c in PATH, mode 040777 Loading development environment (Rails 5.2.2) irb(main):001:0> User.find(6) User Load (1.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 6], ["LIMIT", 1]] Traceback (most recent call last): 1: from (irb):1 ActiveRecord::RecordNotFound (Couldn't find User with 'id'=6) irb(main):002:0>

‘‘‘ ruby入門を再読し、gemfileでpry-railsを記述し、コンソールでbundle installして、エラーが出ているアクションのshowのdef show @user = User.find(params[:id]) の下にbinding.pryを入力しました。 その後にrails sでサーバーを立ち上げ、現在エラーが出ているページをリロードしましたが、コンソールでブレークポイントで処理が止まったことを知らせる表示が出ませんでした。 サーバー起動後のbinding.pryの使い方について御教授願えませんでしょうか。

RYUTAONO0929 commented 5 years ago

Couldn't find User with 'id'=6 ですが、Userモデルをid 6番のカラムとともに発見できなかったということだと解釈しました。

konchanxxx commented 5 years ago

あれ、またコードスニペットのやり方間違ってますね

現在エラーが出ているページをリロードしましたが

リロードした時ってどんなリクエストが出ていますか?コンソールに出力されているとそのリクエストとルーティングで定義は一致しているでしょうか?def show の処理を通るにはリクエストが定義したものになってルーティングされる必要があります。 https://diveintocode.jp/tips/routing01 binding.pryの使い方はあっています。

konchanxxx commented 5 years ago

Couldn't find User with 'id'=6 ですが、Userモデルをid 6番のカラムとともに発見できなかったということだと解釈しました。

はい、こちらOKです:smile: 正確には

Userモデルと紐づいているusersテーブルのid=6のレコードが存在しなかった

と言う表現になるかなと思います:bow:

RYUTAONO0929 commented 5 years ago

ルーティングは以下のようになっています。

ryutaono@DESKTOP-G6D20US:~/taskleaf$ bundle exec rake routes
                   Prefix Verb   URI Pattern                                                                              Controller#Action
                    login GET    /login(.:format)                                                                         sessions#new
                          POST   /login(.:format)                                                                         sessions#create
                   logout DELETE /logout(.:format)                                                                        session#destroy
              admin_users GET    /admin/users(.:format)                                                                   admin/users#index
                          POST   /admin/users(.:format)                                                                   admin/users#create
           new_admin_user GET    /admin/users/new(.:format)                                                               admin/users#new
          edit_admin_user GET    /admin/users/:id/edit(.:format)                                                          admin/users#edit
               admin_user GET    /admin/users/:id(.:format)                                                               admin/users#show
                          PATCH  /admin/users/:id(.:format)                                                               admin/users#update
                          PUT    /admin/users/:id(.:format)                                                               admin/users#update
                          DELETE /admin/users/:id(.:format)                                                               admin/users#destroy
                     root GET    /                                                                                        tasks#index
                    tasks GET    /tasks(.:format)                                                                         tasks#index
                          POST   /tasks(.:format)                                                                         tasks#create
                 new_task GET    /tasks/new(.:format)                                                                     tasks#new
                edit_task GET    /tasks/:id/edit(.:format)                                                                tasks#edit
                     task GET    /tasks/:id(.:format)                                                                     tasks#show
                          PATCH  /tasks/:id(.:format)                                                                     tasks#update
                          PUT    /tasks/:id(.:format)                                                                     tasks#update
                          DELETE /tasks/:id(.:format)                                                                     tasks#destroy
       rails_service_blob GET    /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET    /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
       rails_disk_service GET    /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT    /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
     rails_direct_uploads POST   /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create
ryutaono@DESKTOP-G6D20US:~/taskleaf$

users_controller.rbはこんな感じです。

class Admin::UsersController < ApplicationController
  def new
    @user = User.new
  end
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to admin_users_path, notice: 'ユーザー「#{@user.name}」を登録しました。'
    else
      render :new
    end
  end

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

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

  end

  def index
    @users = User.all
  end
  def update
    @user = User.find(params[:id])

    if @user.update(user_params)
      redirect_to admin_user_path(@user), notice: "ユーザー 「#{@user.name}」を更新しました。"
    else
      render :new
    end

  end
  def destroy
    @user = User.find(params[:id])
    @user.destroy
    redirect_to admin_users_url, notice: "ユーザー「#{@user.name}」を削除しました。"
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :admin, :password, :password_confirmation )
  end
end
h1 Admin::Users#show
p Find me in app/views/admin/users/show.html.slim

h1 ユーザーの詳細

.nav.justify-content-end
  =link_to '一覧', admin_users_path, class: 'nav-link'
table.table.table-hover
  tbody
    tr
      th= User.human_attribute_name(:id)
      td= @user.id
    tr
      th= User.human_attribute_name(:name)
      d= @user.name
    tr
      th= User.human_attribute_name(:email)
      td= @user.email
    tr
      th= User.human_attribute_name(:admin)
      td= @user.admin? ? 'あり' : 'なし'
    tr
      th= User.human_attribute_name(:created_at)
      td= @user.created_at
    tr
      th= User.human_attribute_name(:updated_at)
      td= @user.updated_at

= link_to '編集', edit_admin_user_path, class: 'btn btn-primary mr-3'
= link_to '削除', [:admin, @user], method: :delete, data: {confirm: 'ユーザー「#{@user.name}」を削除します。よろしいですか?'}, class: 'btn btn-danger'

show.htmlはこんな感じです

RYUTAONO0929 commented 5 years ago

PCを再起動したときに例によってパーミッションをchmod -R 755 ~で正常に戻したところ解決したので、パーミッションの問題だったのかもしれません

konchanxxx commented 5 years ago

画面リロードした時のコンソールの出力結果はどうなりますか?

PCを再起動したときに例によってパーミッションをchmod -R 755 ~で正常に戻したところ解決したので、パーミッションの問題だったのかもしれません

これは元のエラーが解消したということでしょうか? id=6が存在しないエラーが解消したということは再起動でデータが取得できたということです?

RYUTAONO0929 commented 5 years ago

返信遅れました。 users_controller.rbのshowアクションの中にbinding.pryを入力し、admin/usersを表示させた時のコンソールは以下のようなものです。

ryutaono@DESKTOP-G6D20US:~/taskleaf$ rails s
/home/ryutaono/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.2/lib/rails/app_loader.rb:53: warning: Insecure world writable dir /mnt/c in PATH, mode 040777
=> Booting Puma
=> Rails 5.2.2 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.0-p0), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
Started GET "/admin/users" for 127.0.0.1 at 2019-03-16 11:41:36 +0100
   (1.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
  ↳ vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/log_subscriber.rb:98
Processing by Admin::UsersController#index as HTML
  Rendering admin/users/index.html.slim within layouts/application
  User Load (1.5ms)  SELECT "users".* FROM "users"
  ↳ app/views/admin/users/index.html.slim:19
  Rendered admin/users/index.html.slim within layouts/application (105.1ms)
Completed 200 OK in 664ms (Views: 640.1ms | ActiveRecord: 9.4ms)

元のエラー(id=6が見つからない問題)は一日置いたらなぜか解決しました。

RYUTAONO0929 commented 5 years ago

users_controller.rbの中はこんな感じです

class Admin::UsersController < ApplicationController
  def new
    @user = User.new
  end
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to admin_users_path, notice: 'ユーザー「#{@user.name}」を登録しました。'
    else
      render :new
    end
  end

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

  def show
    @user = User.find(params[:id])
    binding.pry

  end

  def index
    @users = User.all
  end

Gemfileはこんな感じです。

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.0'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.2'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby

# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
gem 'bcrypt', '~> 3.1.7'

# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
  gem 'pry-rails'
  gem 'better_errors'
  gem 'binding_of_caller'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of chromedriver to run system tests with Chrome
  gem 'chromedriver-helper'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

gem 'slim-rails'
gem 'html2slim'

gem 'bootstrap'
konchanxxx commented 5 years ago

users_controller.rbのshowアクションの中にbinding.pryを入力し、admin/usersを表示させた時のコンソールは以下のようなものです。

表示させたっていうのはページをリロードしたってことですよね?

Started GET "/admin/users" for 127.0.0.1 at 2019-03-16 11:41:36 +0100
   (1.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
  ↳ vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.2/lib/active_record/log_subscriber.rb:98
Processing by Admin::UsersController#index as HTML

の部分はどう解釈していますか?

konchanxxx commented 5 years ago

あとソースコード貼ってもらうだけだと原因がある?と想定している箇所以外のコードが見れなくて限界があるのでGitHubのリポジトリにあげてもらうことできるでしょうか? private リポジトリとかで私のアカウントをcollaboratorに追加してもらえればと思います:bow:

RYUTAONO0929 commented 5 years ago

Admin::UsersController#index as HTMLはもしや、index.html.slimを読み込んでいるということでしょう?

RYUTAONO0929 commented 5 years ago

プライベートリポジトリを作ってcollaboratorで追加しました。 これからは、問題となっているファイルのコードをプライベートリポジトリに載せて、質問内容をこのイシューに書き込むことで良いのでしょうか?

konchanxxx commented 5 years ago

ですね。 GET "/admin/users" のところがリクエストを表しているのでそれに該当する処理がルーティングされて処理されます。 https://wa3.i-3-i.info/word1841.html

GET "/admin/users" に該当するルーティング定義ってどれかわかりますか?

RYUTAONO0929 commented 5 years ago
admin_user GET    /admin/users/:id(.:format)                                                               admin/users#show

となっています

konchanxxx commented 5 years ago

あーそれだと

GET /admin/users/6 みたいなリクエストになるはずです

konchanxxx commented 5 years ago

:id(.:format) の部分が任意の数字が入るプレースホルダを表しているのでid指定されている場合はそのルーティング定義を使いますがそれ以外の場合は別のルーティング定義になります。 今回の場合だと GET "/admin/users" でプレースホルダに該当するidがないので違いますね

RYUTAONO0929 commented 5 years ago
GET    /admin/users(.:format)                                                                   admin/users#index

こちらが正解でしょうか

konchanxxx commented 5 years ago

ですです

じゃあそのルーティング定義はどの処理にHTTPリクエストをルーティングしているかわかりますか?

RYUTAONO0929 commented 5 years ago

indexアクションでしょうか?

konchanxxx commented 5 years ago

そうですね 正確には admin/users#index となっているので admin/usersコントローラーindex アクションということになっています なのでshowアクション は通ってないです そのためbinding.pryで処理が止まらないです

RYUTAONO0929 commented 5 years ago

showアクションを通すためには,どのHTTPリクエストをすればよいのでしょうか? admin_user GET /admin/users/:id(.:format) admin/users#show なので、 /admin/users/:id(.:format) でしょうか

konchanxxx commented 5 years ago

そうですね それで良いです:bow: リロードじゃなくて一覧から遷移するとかすれば良いと思いますmm

RYUTAONO0929 commented 5 years ago
[1] pry(#<Admin::UsersController>)> Started GET "/admin/users/12" for 127.0.0.1 at 2019-03-16 13:01:58 +0100
Processing by Admin::UsersController#show as HTML
  Parameters: {"id"=>"12"}
  User Load (1.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 12], ["LIMIT", 1]]
  ↳ app/controllers/admin/users_controller.rb:19

From: /home/ryutaono/taskleaf/app/controllers/admin/users_controller.rb @ line 20 Admin::UsersController#show:

    18: def show
    19:   @user = User.find(params[:id])
 => 20:   binding.pry
    21:
    22:
    23:
    24: end

[1] pry(#<Admin::UsersController>)>

表示されました。 御指導有難うございました。

konchanxxx commented 5 years ago

はい:bow:

Started GET "/admin/users/12" がHTTPリクエストでそれがルーティング定義である

admin_user GET    /admin/users/:id(.:format)                                                               admin/users#show

に従ってルーティングされているというところはしっかり抑えておくとRailsの挙動を理解するキッカケになると思います:bow: