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です。
回答2件
あなたの回答
tips
プレビュー