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

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

ただいまの
回答率

88.77%

サインイン機能でsaveができない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 741
退会済みユーザー

退会済みユーザー

索引
0、使っている環境
1、目的
2、問題点
3、提供できるデータ
上記索引順に記述しています。

0、使っている環境
Rails 5.2.3
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin17]

1,目的
サインイン機能を実装し、Viewの方からその操作が滞りなく進むこと。

2,問題点
Userコントローラでcreateアクションを実行する際に、データベースの中身でnulのものがあるらしく、サインインができない。
なぜcreateアクションに問題があるかは下記の内容で調べたと考えています。ご参照ください。
エラーコードは、

Unknown column 'users.password' in 'where clause': SELECT 1 AS one FROM `users` WHERE `users`.`password` IS NULL LIMIT 1


でした。

3,提供でき、これがあれば理解していただけるのではないか?と考えられるデータ
migrationファイル、modelのファイル、controllerのファイル、viewのファイル。rails consoleで確認したこと。
※他に必要であれば何でも言ってください、提供できるデータはすべて提供します。
また、自分で解決を図り、試したことでわかったことについても記述します。
お時間あればご回答いただけると幸いです。よろしくお願いします。

3-1,省略/migrate/省略_create_users.rb(maigrationファイル)

class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email


      t.timestamps
    end
  end
end

3-2,省略/models/user.rb(modelファイル)

class User < ApplicationRecord
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :name, presence: true ,length: {maximum:20},uniqueness: true
  validates :email, presence: true, uniqueness: true,format: { with: VALID_EMAIL_REGEX }

  #パスワード用のバリデーション・正規表現
  #PASS_WORD_REGEX = /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]{5,100}+\z/i
  has_secure_password
  validates :password, presence:true, uniqueness:true, length: {maximum:72}#,format: {with:PASS_WORD_REGEX}
end

3-3,app/asset/controllers/users_controller.rb(controllerファイル)

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to root_path
      flash[:success] = "登録に成功しました"
    else
      flash[:danger] = "登録に失敗しました。登録した情報に空欄があるか、またはすでに使用され重複している可能性があります"
      render :new
    end
  end

  #privateメソッドでこのコントローラ内部でのみ動くクラスを定義した。ストロングパラメータを定義。
  private
  def user_params
    params.require(:user).permit(:name, :email, :password_digest)
  end
end


ここのcreateアクションで問題発生。

3-4,app/asset/views/users/new.html.erb(viewファイル)

<div class="users-new-wrapper">
  <div class="container">
    <div class="row">
      <div class="col-md-offset-4 col-md-4 users-new-container">
        <h1 class="text-center text-white">Sign up</h1>
        <%= form_for @user do |f| %>
          <div class="form-group">
            <%= f.label :name, class: 'text-white' %>
            <%= f.text_field :name, class: 'form-control' %>
          </div>
          <div class="form-group">
            <%= f.label :email, class: 'text-white' %>
            <%= f.text_field :email, class: 'form-control' %>
          </div>
          <div class="form-group">
            <%= f.label :password, class: 'text-white' %>
            <%= f.text_field :password, class: 'form-control' %>
          </div>
          <div class="form-group">
            <%= f.label :password_confirmation, class: 'text-white' %>
            <%= f.text_field :password_digest, class: 'form-control' %>
          </div>

          <%= f.submit "登録", class: 'btn-block btn-white' %>
        <% end %>
        <%= link_to 'ログインはこちら', login_path,class: 'text-white' %>
      </div>
    </div>
  </div>
</div>

4,試したことおよびrails consoleよりわかったこと

4-1,Userテーブルがどうなっているのか確認。

[1] pry(main)> User.column_names
   (0.4ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
=> ["id", "name", "email", "created_at", "updated_at", "password_digest"]

4-2,Userコントローラで何ができないのかの確認。まずは、User.newから。

[2] pry(main)> user1 = User.new(name:'asdf',email:'test1@test.com',password_digest:'asdfghjkl')

=> #<User:0x007fc7f152c310
 id: nil,
 name: "asdf",
 email: "test1@test.com",
 created_at: nil,
 updated_at: nil,
 password_digest: "asdfghjkl">

→なぜかidに番号が入らないのを不思議だと感じながらも、一応はできている?みたい。
なので、それぞれのカラムに適当なものを打ち込んで、saveができるかを以下で確認する。

4-3,user1.saveを試してみる。

[3] pry(main)> user1.save                                                       
   (0.2ms)  BEGIN
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`name` = BINARY 'asdf' LIMIT 1
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'test1@test.com' LIMIT 1
  User Exists (1.4ms)  SELECT  1 AS one FROM `users` WHERE `users`.`password` IS NULL LIMIT 1
   (0.2ms)  ROLLBACK
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'users.password' in 'where clause': SELECT  1 AS one FROM `users` WHERE `users`.`password` IS NULL LIMIT 1
from /Users/horiguchihiroki/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/mysql2-0.5.2/lib/mysql2/client.rb:131:in `_query'
Caused by Mysql2::Error: Unknown column 'users.password' in 'where clause'
from /Users/horiguchihiroki/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/mysql2-0.5.2/lib/mysql2/client.rb:131:in `_query'


→なぜか存在しているかのような返答をもらえたので、どういうこと?と確認の意味で、find_byで探してみる。

4-4,User.find_by(name:'asdf')で、確認。

[4] pry(main)> user2 = User.find_by(name:'asdf')
  User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`name` = 'asdf' LIMIT 1
=> nil


→いやないじゃん。User.saveができていないらしいということがここで確認できたと考えています。ここからの打開策を自分では計っているのですが、なかなか解決できないのでそもそもの着眼点自体が異なるのではないか?ということでこちらで質問をさせていただきます、よろしくお願いします。

(後日編集箇所)ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
tktktさんありがとうございます!以下にpassword_digestをaddしているファイルの中身を記載します。
これで、password_digestは設定できていると考えているのですが、この認識はあっていますでしょうか?

class AddPasswordDigestToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :password_digest, :string
  end
end
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • urbainleverrier

    2019/05/20 23:18

    migrationファイルでpassword_digestがありませんが、他のファイルで設定されていますか?
    エラーの内容はpasswordカラムがないということです。
    おそらく、以下のあたりでエラーが起きているんだと思います。
    ```
    validates :password, presence:true, uniqueness:true, length: {maximum:72}
    ```
    エラーの最後、`IS NULL`とは、user.passwordがnullということで、本当はuser.password_digestに値が入っているのではないですか?
    user.idに値が入らないのは、mysqlのincrement機能の恩恵をまだ得ていないからです。saveすれば入ります。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2019/05/21 21:48 編集

    tktktさん、ご回答ありがとうございます!
    password_digestに関しては、編集で載せたコードから設定できていると認識しております。

    指摘いただいているエラー部分に関しては、passwordカラムではなく、password_digestカラムにバリデーションをかけるべきということですよね。試してみます!
    ご指摘本当にありがとうございました。バリデーションをかける部分を間違っておりました。正常に、ユーザ登録することができました、本当にありがとうござました。

    キャンセル

回答 1

check解決した方法

0

とりあえず解決しました、バリデーションをかける部分にミスがあったようでした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る