Rails应用Heroku生产环境密码重置功能失效求助
reset_digest= undefined) Hey there, let's break down why your password reset is throwing a 500 on Heroku but working locally—this is a classic "works on my machine" scenario with a few common fixes:
1. First: Verify Your Production Database Has the Required Columns
The NoMethodError: undefined method 'reset_digest=' almost always means your Heroku production database is missing the reset_digest (and likely reset_sent_at) columns that your local database has. Here's how to fix that:
- Run migrations on Heroku to sync your schema:
heroku run rails db:migrate - Double-check the columns exist by firing up the Heroku Rails console:
Then run this command to confirm:heroku run rails console
If this returnsUser.column_names.include?('reset_digest') && User.column_names.include?('reset_sent_at')false, you either forgot to run migrations, or your migration file for adding these columns is missing/incorrect. Go back to your local codebase and confirm you have a migration file (likedb/migrate/[timestamp]_add_reset_digest_to_users.rb) with content like:
If the migration is missing, generate it locally, runclass AddResetDigestToUsers < ActiveRecord::Migration[7.0] def change add_column :users, :reset_digest, :string add_column :users, :reset_sent_at, :datetime end endrails db:migrate, commit the file, and redeploy to Heroku.
2. Check Your create_reset_digest Method for Typos or Missing self
Even if the column exists, a small code mistake can cause this error. Make sure your User model's create_reset_digest method is correctly referencing the attribute. Here's the correct implementation from the Rails Tutorial:
class User < ApplicationRecord # ... other code ... def create_reset_digest self.reset_token = User.new_token update_attribute(:reset_digest, User.digest(reset_token)) update_attribute(:reset_sent_at, Time.zone.now) end # ... other code ... end
- Common mistakes here:
- Forgetting
selfwhen assigningreset_token(withoutself, Ruby creates a local variable instead of setting the instance attribute) - Typos like
reset_digist=instead ofreset_digest= - Using
update_attributes(plural) instead ofupdate_attribute(singular) or not saving the changes at all
- Forgetting
3. Clear Heroku's Cache and Redeploy
Rails precompiles assets and caches code in production, so sometimes recent model changes don't make it to Heroku even after a push. Try purging the cache and redeploying:
heroku repo:purge_cache git push heroku main # or your default branch name
4. Confirm Local vs. Heroku Rails Versions Match
Mismatched Rails versions can cause unexpected method errors. Check your local version:
rails -v
And your Heroku version:
heroku run rails -v
If they don't match, update your Gemfile to lock the correct Rails version, run bundle install, commit the changes, and redeploy.
5. Dig Deeper Into the Heroku Error Stack
Take another look at the full Heroku error log (run heroku logs --tail to see real-time logs) to find exactly where reset_digest= is being called. Sometimes the error originates in a controller action or mailer template instead of the model—for example, if you accidentally wrote @user.reset_digest = some_value in your password reset controller instead of using the create_reset_digest method.
Start with step 1 first—9 times out of 10, this is a migration issue where the production database hasn't caught up to your local schema.
内容的提问来源于stack exchange,提问作者user13284529

