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

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

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

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

Ruby on Rails 6

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

Q&A

解決済

1回答

378閲覧

bcryptを使ってUserをActiveJobを用いて作成したらエラー(Unknown column 'users.password' in 'where clause')が起きる

keiino0425

総合スコア2

Ruby

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

Ruby on Rails 6

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

0グッド

0クリップ

投稿2022/10/02 08:15

前提

railsを使ってアプリケーションを開発しています。
https://qiita.com/kazama1209/items/a08fe0d25384b4a6ea99
こちらの記事を参考にして、
①スプレッドシートの値を読み取る
②その値を元にUserモデルを作成する
③Userがマイページ(viewファイル)から自分の情報を読み取ることができる

というログイン機能つきのマイページを作成しようとしています。

bcryptのhas_secure_passwordを用いて、ハッシュ化されたパスワードを利用しようと考えています。

以下、主なコードです。

schema.rb

1ActiveRecord::Schema.define(version: 2022_09_30_122620) do 2 3 create_table "users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| 4 t.string "user_name" 5 t.integer "chip" 6 t.integer "winning_streak" 7 t.integer "point" 8 t.integer "a_rule_game" 9 t.integer "a_rule_first_place" 10 t.integer "a_rule_second_place" 11 t.integer "a_rule_third_place" 12 t.integer "a_rule_rating" 13 t.datetime "created_at", precision: 6, null: false 14 t.datetime "updated_at", precision: 6, null: false 15 t.integer "b_rule_game" 16 t.integer "b_rule_first_place" 17 t.integer "b_rule_second_place" 18 t.integer "b_rule_third_place" 19 t.integer "b_rule_rating" 20 t.string "password_digest" 21 end 22 23end

user.rb

1class User < ApplicationRecord 2 has_secure_password 3end

spreadsheets.rb

1require "google/apis/sheets_v4" 2 3module Google 4 class Spreadsheets 5 def initialize 6 @service = Google::Apis::SheetsV4::SheetsService.new 7 @service.authorization = authorize 8 end 9 10 # 認証 11 def authorize 12 json_key = JSON.generate( 13 private_key: ENV['GOOGLE_PRIVATE_KEY'], 14 client_email: ENV['GOOGLE_CLIENT_EMAIL'] 15 ) 16 17 json_key_io = StringIO.new(json_key) 18 19 authorizer = Google::Auth::ServiceAccountCredentials.make_creds( 20 json_key_io: json_key_io, 21 scope: ["https://www.googleapis.com/auth/spreadsheets"] 22 ) 23 authorizer.fetch_access_token! 24 authorizer 25 end 26 27 # 指定されたスプレッドシートIDとレンジ(範囲)から値を取得 28 def values(spreadsheet_id, ragne) 29 @service.get_spreadsheet_values(spreadsheet_id, ragne) 30 end 31 end 32end 33

spreadsheets_import_job.rb

1class SpreadsheetsImportJob < ApplicationJob 2 queue_as :default 3 4 # 行の構造を定義 5 Row = Struct.new( 6 :user_name, 7 :password, 8 :chip, 9 :winning_streak, 10 :point, 11 :a_rule_game, 12 :a_rule_first_place, 13 :a_rule_second_place, 14 :a_rule_third_place, 15 :a_rule_rating, 16 :b_rule_game, 17 :b_rule_first_place, 18 :b_rule_second_place, 19 :b_rule_third_place, 20 :b_rule_rating 21 ) 22 23 def perform(spreadsheet_id, range) 24 res = google_spreadsheet_service.values(spreadsheet_id, range) 25 return if res.values.empty? # 値が空だった場合はここで終了 26 27 res.values.drop(1).each do |row_data| # 1行目はヘッダーなので削除 28 row = Row.new(*row_data) 29 attributes = row.to_h.slice( 30 :user_name, 31 :password, 32 :chip, 33 :winning_streak, 34 :point, 35 :a_rule_game, 36 :a_rule_first_place, 37 :a_rule_second_place, 38 :a_rule_third_place, 39 :a_rule_rating, 40 :b_rule_game, 41 :b_rule_first_place, 42 :b_rule_second_place, 43 :b_rule_third_place, 44 :b_rule_rating 45 ) 46 47 # 重複するデータを作成したくないのでfind_or_initialize_byを使用 48 user = User.find_or_initialize_by(attributes) 49 user.save 50 end 51 end 52 53 private 54 55 def google_spreadsheet_service 56 @google_spreadsheet_service ||= Google::Spreadsheets.new 57 end 58end 59

sessions_controller.rb

1class SessionsController < ApplicationController 2 def new; end 3 4 def create 5 SpreadsheetsImportJob.perform_now("1MDPFwFVab9_xnbPcMV2eMCd6PwVF_to6FMMytd54wwA", ["データ読取用!A:O"]) 6 user = User.find_by(user_name: params[:session][:user_name]) 7 if user&.authenticate(params[:session][:password]) 8 log_in user 9 redirect_to user 10 else 11 flash.now[:danger] = '名前かパスワードが正しくありません!' 12 render 'new' 13 end 14 end 15 16 def destroy 17 log_out 18 redirect_to 'new' 19 end 20end 21

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

sessions_controllerのcreateメソッドを利用するときにSpreadsheetsImportJob.perform_now("1MDPFwFVab9_xnbPcMV2eMCd6PwVF_to6FMMytd54wwA", ["データ読取用!A:O"])
というactive jobを使いますが、そのjobを実行する際にusersテーブルにpasswordカラムが存在しないというエラーが発生します。
イメージ説明

ActiveRecord::StatementInvalid (Mysql2::Error: Unknown column 'users.password' in 'where clause')

active jobでUserモデルが上手く作動せずにエラーが起こっているのかと思うのですが、調べてみても解決策が浮かばないため質問させていただきました。

試したこと

has_secure_passwordがUserモデル内で作動しておらず、passwordカラムが利用できないのかと思い、コンソール上でデータを作成しましたが、
Alice = User.new(user_name: "Alice", password: "2345678")
でユーザーを作成し、
Alice.passwordとしたところ2345678、
Alice.password_digestとしたところハッシュ化された文字列が出てきました。

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

ruby 2.7.5
rails 6.1.6
bcrypt 3.1.7

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

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

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

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

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

guest

回答1

0

ベストアンサー

passwordカラムが利用できないのかと思い

はい、passowrdという列が存在しない以上、検索対象にはできません。

find_or_initialize_byに与える条件を減らして、残りはcreate_withで与える、という形にするのがいいかと思います。

投稿2022/10/02 11:06

maisumakun

総合スコア145023

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

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

maisumakun

2022/10/02 11:10

password_digestも、ソルトを付けてハッシュ化している以上、同じパスワードでもデータ内容は一致せず、検索の対象とすることは事実上できません。
keiino0425

2022/11/14 12:37

返信遅くなりました、すいません... ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.53%

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

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

質問する

関連した質問