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

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

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

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

Ruby on Rails

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

Q&A

解決済

2回答

727閲覧

ログインしなくてもusers/showが見れる方法

anpnt

総合スコア29

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2018/09/14 06:01

編集2018/09/14 07:12

Userテーブルに管理者と一般ユーザーをenumで作って、 管理者がユーザー一覧を取得し、一般ユーザーのshowもeditもできるようにするにはどうしたらいいでしょうか?

ユーザーテーブルに紐づけられた作業時間を記録するテーブルや、ログインログアウト時間を記録するテーブルのコントローラーの中で、idがcurrent_userであることを条件にwhereしたりcreateしたりしているのですが、おそらくそれが原因でURLのusers/idの、idがcurrent_userのものでないとエラーが出てしまいます....

viewの中で、上記二つのコントローラーが絡む表示だけをif文でわければいいと思ったのですが、そういうわけでもないようです。

※本当は管理者テーブルを別に作った方がifとか使わなくても綺麗なんでしょうが、そこは質問の本筋とは違うので一旦保留にしてます。。。

モデルはこのようになってます。

user.rb

class User < ApplicationRecord authenticates_with_sorcery! has_many :working_hours, dependent: :destroy has_many :login_logs, dependent: :destroy validates :password, length: { minimum: 3 }, if: -> { new_record? || changes[:crypted_password] } validates :password, confirmation: true, if: -> { new_record? || changes[:crypted_password] } validates :password_confirmation, presence: true, if: -> { new_record? || changes[:crypted_password] } enum usertype: {admin: 0, user: 1} end

working_hour.rb

class LoginLog < ApplicationRecord belongs_to :user end

login_log.rb

class LoginLog < ApplicationRecord belongs_to :user end

working_hourテーブルは
・user_id
・start_datetime
・finish_datetime

login_logテーブルは
・user_id
・login_at
・logout_at
・login_from_ip_address

をそれぞれ持っていて

working_hours_controller.rbは

class WorkingHoursController < ApplicationController def register_work_starting_datetime working_hour = WorkingHour.create(user_id: current_user.id, start_datetime: Time.current) redirect_to controller: "users", action: "show", id: current_user.id end def register_work_finished_datetime working_hour = WorkingHour.where(user_id: current_user.id, finish_datetime: nil).last working_hour.finish_datetime = Time.current working_hour.save redirect_to controller: "users", action: "show", id: current_user.id end end

で、作業ボタンをviewに設置して、そのタイミングで開始時間終了時間を記録する流れになってます。

login_logs_controller.rbはなくて、application_controllerの中で

class ApplicationController < ActionController::Base protect_from_forgery with: :exception protected #sorceryのモジュール"activity_logging"のメソッドを上書き #https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/controller/submodules/activity_logging.rb def register_login_time_to_db(user, credentials) super(user, credentials) LoginLog.create(user_id: current_user.id, login_at: user.last_login_at) end def register_logout_time_to_db super login_log = LoginLog.where(user_id: current_user.id, logout_at: nil).last login_log.logout_at = current_user.last_logout_at login_log.save end def register_last_ip_address(user, credentials) super(user, credentials) login_log = LoginLog.where(user_id: current_user.id, login_from_ip_address: nil).last login_log.login_from_ip_address = current_user.last_login_from_ip_address login_log.save end end

もともとsorceryには活動時間を記録するモジュールがあり、それを上書きする形で

class SorceryActivityLogging < ActiveRecord::Migration[5.0] def change add_column :users, :last_login_at, :datetime, :default => nil add_column :users, :last_logout_at, :datetime, :default => nil add_column :users, :last_activity_at, :datetime, :default => nil add_column :users, :last_login_from_ip_address, :string, :default => nil add_index :users, [:last_logout_at, :last_activity_at] end end

これらのlast_login_atをlogin_atに、last_logout_atをlogout_atに、last_login_from_ip_addressをlogin_from_ip_addressに移す処理を行なっています。

エラーの内容はundefined method `id' for nil:NilClassです。

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

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

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

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

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

spookybird

2018/09/14 06:03

どういう実装をしているのか、なんというエラーが出るのか、それがわからないと回答のしようがないです。
anpnt

2018/09/14 06:26

すみません、追加しました
guest

回答2

0

ベストアンサー

タイトルと内容が若干噛み合っていないような気がするので推測で書くのですが、一般ユーザーと管理者ユーザーで一つのUsersControllerを共有しているため、複雑になっている気がします。

こういう場合は管理者用のUsersControllerと、一般ユーザー用のUsersControllerに分けるべきです。その場合 routes.rb は次のようになります。

ruby

1Rails.application.routes.draw do 2 resources :users #一般用 3 namespace :admin do 4 resources :users #管理者用 5 end 6end 7

管理者用のControllerは app/controllers/admin 以下に設置しましょう。routes.rb + namespace 等でググると理解が深まるかと思います。

投稿2018/09/14 06:23

kazuhisa

総合スコア44

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

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

anpnt

2018/09/14 06:43 編集

おお、、、そんな方法が、、、ありがとうございます。 ちなみにそこまでするなら、管理者テーブルを作った方がいいですかね?(管理者ユーザーが複数いたり、今後管理レベルを分ける可能性がある場合)
kazuhisa

2018/09/14 06:50

システムの全容がよくわからないまま回答しますが、おそらく管理者ユーザーも一般ユーザーと同等の操作ができる必要があるのではないでしょうか。 その場合、テーブルを分ける(つまりモデルを分ける)と複雑になりすぎます。 現状Userモデルにenumで権限管理できているのであればそれで充分かと思います。管理レベルを増やす際も `enum usertype` の内容を増やして制御しましょう。
anpnt

2018/09/14 07:16

ちなみにその方法をとった場合でも、管理者にログインした状態でuser/idというURLで一般ユーザーのshowに飛ぶ場合、例えばworking_hours_controllerでcurrent_userに絡む処理を入れていると出るエラーはそのままだと解決しないですよね?
kazuhisa

2018/09/14 14:40

初めの質問およびコードを見直した上で、↑の質問の意味を考えてみたのですが理解できませんでした。 ひとつアドバイスできるとすると、current_user基準で処理するControllerとパラメータを元にユーザーをDBから取得して処理するControllerは分けたほうが良いということです。
anpnt

2018/09/15 00:08

なるほど...! ありがとうございます!
anpnt

2018/09/15 08:25 編集

ベストアンサーを決めたあとで申し訳ないのですが、もしかしたら意図が伝わるかもしれない文章がかけそうなので追加でコメントさせていただきます。。。伝わらなかったら本当にすみません。 working_hours_controllerを作るなどで、controllerを分けているんですが、そのworking_hours_controller部分でundefined method `id' for nil:NilClassのエラーがでます。 そのエラーはログインしてるユーザーとは別のユーザーで状態でuser/showにアクセスしているので、user/show内で使われるcontrollerの中でcurrent_userのidを使う処理をしているから怒られてるという流れだと思うんですけど、その場合はログインしていない状態ではそのcontrollerは無視?されるような処理 って、そもそもcurrent_userのidでデータべースから取ってくるという処理自体を見直した方がいいんですかね?
guest

0

条件を追加したり、管理者権限用のリソースを新たに作ったりすればできますがコード量も増えます。
この先を考えてもrails_adminやactive_adminといったgemを利用するのが一番手っ取り早いような気がします...。

投稿2018/09/14 06:08

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問