🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Cloud9

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Ruby

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

Ruby on Rails

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Q&A

解決済

1回答

1000閲覧

[rails]duplicate column name: reset_sent_atと表示されるが重複している箇所がわからない

outmysd

総合スコア3

Cloud9

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Ruby

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

Ruby on Rails

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

0グッド

0クリップ

投稿2020/12/26 12:04

#分からないこと
railsチュートリアルの演習でマイクロポストの作成を行っているのですが、root_urlに移動すると

StandardError An error has occurred, this and all later migrations canceled: SQLite3::SQLException: duplicate column name: reset_sent_at

とエラーが表示されてしまいます。
Userのreset_sent_atカラムが重複しているというのはわかるのですが、どこがどう重複しているのかがいまいちわかりません。このエラーの解決方法についてどなたかアドバイスをいただければありがたいです。

#関連しそうなファイル

#app/models/user.rb class User < ApplicationRecord has_many :microposts attr_accessor :remember_token, :activation_token, :reset_token before_save { email.downcase! } before_create :create_activation_digest validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: true has_secure_password validates :password, presence: true, length: { minimum: 6 }, allow_nil: true # 渡された文字列のハッシュ値を返す def User.digest(string) cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost BCrypt::Password.create(string, cost: cost) end # ランダムなトークンを返す def User.new_token SecureRandom.urlsafe_base64 end # 永続セッションのためにユーザーをデータベースに記憶する def remember self.remember_token = User.new_token update_attribute(:remember_digest, User.digest(remember_token)) end # 渡されたトークンがダイジェストと一致したらtrueを返す def authenticated?(remember_token) return false if remember_digest.nil? BCrypt::Password.new(remember_digest).is_password?(remember_token) end # トークンがダイジェストと一致したらtrueを返す def authenticated?(attribute, token) digest = send("#{attribute}_digest") return false if digest.nil? BCrypt::Password.new(digest).is_password?(token) end # ユーザーのログイン情報を破棄する def forget update_attribute(:remember_digest, nil) end # アカウントを有効にする def activate update_attribute(:activated, true) update_attribute(:activated_at, Time.zone.now) end # 有効化用のメールを送信する def send_activation_email UserMailer.account_activation(self).deliver_now end # パスワード再設定の属性を設定する def create_reset_digest self.reset_token = User.new_token update_columns(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now) end # パスワード再設定のメールを送信する def send_password_reset_email UserMailer.password_reset(self).deliver_now end # パスワード再設定の期限が切れている場合はtrueを返す def password_reset_expired? reset_sent_at < 2.hours.ago end private # メールアドレスをすべて小文字にする def downcase_email self.email = email.downcase end # 有効化トークンとダイジェストを作成および代入する def create_activation_digest self.activation_token = User.new_token self.activation_digest = User.digest(activation_token) end end
#app/controllers/password_resets_controller.rb class PasswordResetsController < ApplicationController before_action :get_user, only: [:edit, :update] before_action :valid_user, only: [:edit, :update] before_action :check_expiration, only: [:edit, :update] def new end def create @user = User.find_by(email: params[:password_reset][:email].downcase) if @user @user.create_reset_digest @user.send_password_reset_email flash[:info] = "Email sent with password reset instructions" redirect_to root_url else flash.now[:danger] = "Email address not found" render 'new' end end def edit end def update if params[:user][:password].empty? @user.errors.add(:password, :blank) render 'edit' elsif @user.update(user_params) log_in @user @user.update_attribute(:reset_digest, nil) flash[:success] = "Password has been reset." redirect_to @user else render 'edit' end end private def user_params params.require(:user).permit(:password, :password_confirmation) end # beforeフィルタ def get_user @user = User.find_by(email: params[:email]) end # 正しいユーザーかどうか確認する def valid_user unless (@user && @user.activated? && @user.authenticated?(:reset, params[:id])) redirect_to root_url end end # トークンが期限切れかどうか確認する def check_expiration if @user.password_reset_expired? flash[:danger] = "Password reset has expired." redirect_to new_password_reset_url end end end
#config/routes.rb Rails.application.routes.draw do get 'password_resets/new' get 'password_resets/edit' root 'static_pages#home' get '/help', to: 'static_pages#help' get '/about', to: 'static_pages#about' get '/contact', to: 'static_pages#contact' get '/signup', to: 'users#new' get '/login', to: 'sessions#new' post '/login', to: 'sessions#create' delete '/logout', to: 'sessions#destroy' resources :users resources :account_activations, only: [:edit] resources :password_resets, only: [:new, :create, :edit, :update] end
#app/mailers/user_mailer.rb class UserMailer < ApplicationMailer def account_activation(user) @user = user mail to: user.email, subject: "Account activation" end def password_reset(user) @user = user mail to: user.email, subject: "Password reset" end end
#20201223140935_add_reset_to_users.rb class AddResetToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :reset_digest, :string add_column :users, :reset_sent_at, :datetime end end
#20201223141905_add_reset_sent_at_to_users.rb class AddResetSentAtToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :reset_sent_at, :datetime end end
#db/schema.rb ActiveRecord::Schema.define(version: 2020_12_26_033956) do create_table "microposts", force: :cascade do |t| t.text "content" t.integer "user_id", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["user_id", "created_at"], name: "index_microposts_on_user_id_and_created_at" t.index ["user_id"], name: "index_microposts_on_user_id" end create_table "users", force: :cascade do |t| t.string "name" t.string "email" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.string "password_digest" t.string "remember_digest" t.boolean "admin", default: false t.string "activation_digest" t.boolean "activated", default: false t.datetime "activated_at" t.string "reset_digest" t.datetime "reset_sent_at" t.index ["email"], name: "index_users_on_email", unique: true end add_foreign_key "microposts", "users" end

#試したこと
rails db:test:prepare
rails db:migrate RAILS_ENV=development
rails db:migrate:reset

20201223140935_add_reset_to_users.rb
20201223141905_add_reset_sent_at_to_users.rb
db/schema.rb

のreset_sent_atの部分をコメントアウトしてみる
=>root_urlにアクセスできたがパスワードリセット画面へ遷移するときエラーが起きた

#環境
CentOS8

#Gemfile source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } gem 'rails', '6.0.3' gem 'bcrypt', '3.1.13' gem 'faker', '2.1.2' gem 'will_paginate', '3.1.8' gem 'bootstrap-will_paginate', '1.0.0' gem 'bootstrap-sass', '3.4.1' gem 'puma', '4.3.6' gem 'sass-rails', '5.1.0' gem 'webpacker', '4.0.7' gem 'turbolinks', '5.2.0' gem 'jbuilder', '2.9.1' gem 'bootsnap', '1.4.5', require: false group :development, :test do gem 'sqlite3', '1.4.1' gem 'byebug', '11.0.1', platforms: [:mri, :mingw, :x64_mingw] end group :development do gem 'web-console', '4.0.1' gem 'listen', '3.1.5' gem 'spring', '2.1.0' gem 'spring-watcher-listen', '2.0.1' end group :test do gem 'capybara', '3.28.0' gem 'selenium-webdriver', '3.142.4' gem 'webdrivers', '4.1.2' gem 'rails-controller-testing', '1.0.4' gem 'minitest', '5.11.3' gem 'minitest-reporters', '1.3.8' gem 'guard', '2.16.2' gem 'guard-minitest', '2.4.6' end group :production do gem 'pg', '1.1.4' end # Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

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

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

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

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

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

guest

回答1

0

ベストアンサー

本当にこれを直すだけでいいのかどうかはわかりませんが、少なくとも重複していて明らかに問題になりそうな箇所は1か所見つけました。

イメージ説明

同じテーブルに対して同じカラム名のカラムを2度作成しているので、これは問題になりそうです。
ただ、この場合、アプリ操作中ではなく、db:migrateした時点でエラーになりそうなものですが....何かのヒントになれば幸いです。

投稿2020/12/26 12:20

siruku6

総合スコア1382

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

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

outmysd

2020/12/26 14:57

reset_sent_atのカラムの部分をコメントアウトしてみたのですが同じようなエラーが出てしまいました。もしかするとデータベースがおかしくなってしまっているのかもしれません。
siruku6

2020/12/26 23:14

そうですね、migrationファイルは、基本的に書き換えただけでは効力を発揮しません。 rails db:migrateや、rails db:rollbackのようなコマンドを実行することによって初めてデータベースに変更を加えることができます。 もし、中に入っているデータが消えても良いのであれば、一度migrationファイルを綺麗に整理した上で、rails db:migrate:resetを実行することで、実行時の全migrationファイルの状態をまとめて一度に反映させることが可能です。
outmysd

2020/12/27 05:03

その方法も試してみます!親切に教えていただきありがとうございます
siruku6

2020/12/27 06:22

上手くいくといいのですが。。。 何か行き詰まったらまたコメントください。
outmysd

2020/12/27 07:52

一から作り直したら何とか元の状態に戻せました! ありがとうございました! もう少し効率的な解決方法を考えた方がいいかもしれませんが、ひとまずこれで学習を進めてみようと思います
siruku6

2020/12/27 08:51

いったん開発が進められるようになったようでよかったです。 応援しています(o*。_。)oペコッ
outmysd

2020/12/27 10:02

ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問