ユーザーモデルを作成しました。ユーザーがサインアップすると、確認メールが送信されます。しかし、私のレールアプリにロケールを追加すると、エラーが発生し始めました。Railsロケールによるユーザーのアクティベーションリンク
ここにはユーザー#作成アクションがあります。
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
flash[:notice] = '..'
format.html { redirect_to root_url }
format.js { render action: 'new', status: :created }
@user.send_activation_email
else
format.html { render action: 'new' }
format.js { render json: @user.errors, status: 404 }
end
end
end
アカウントアクティベーションコントローラ。
class AccountActivationsController < ApplicationController
def edit
user = User.find_by(email: params[:email])
if user && !user.activated? && user.authenticated?(:activation, params[:id])
user.activate
log_in user
flash[:success] = "activated!"
redirect_to user
else
flash[:alert] = "Invalid link"
redirect_to root_url
end
end
end
user.rb
<h1>Sample</h1>
<p>Hi <%= @user.name %>,</p>
<p>
Welcome to ...! Click on the link below to activate your account:
</p>
<%= link_to "Activate", edit_account_activation_url(@user.activation_token,
email: @user.email, locale: @locale) %>
最後に、コンソールからエラーaccount_activation.html.erb最後
# Returns the hash digest of the given string.
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
# Returns a random token.
def User.new_token
SecureRandom.urlsafe_base64
end
# Remembers a user in the database for use in persistent sessions.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
# Activates an account.
def activate
update_attribute(:activated, true)
update_attribute(:activated_at, Time.zone.now)
end
# Sends activation email.
def send_activation_email
UserMailer.account_activation(self).deliver_now
end
# Sets the password reset attributes.
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
# Sends password reset email.
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
# Returns true if a password reset has expired.
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
private
# Converts email to all lower-case.
def downcase_email
self.email = email.downcase
end
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
の一部。
Started POST "/tr/users" for ::1 at 2016-05-18 12:01:24 +0300
I, [2016-05-18T12:01:24.453564 #454] INFO -- : Processing by UsersController#create as JS
I, [2016-05-18T12:01:24.453779 #454] INFO -- : Parameters: {"utf8"=>"✓", "user"=>{"name"=>"234234", "username"=>"234234", "email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "user_type"=>"Personal Account", "terms_of_service"=>"1"}, "commit"=>"Hesap Oluştur", "locale"=>"tr"}
D, [2016-05-18T12:01:24.546048 #454] DEBUG -- : (0.2ms) begin transaction
D, [2016-05-18T12:01:24.547422 #454] DEBUG -- : User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('[email protected]') LIMIT 1
D, [2016-05-18T12:01:24.548145 #454] DEBUG -- : User Exists (0.1ms) SELECT 1 AS one FROM "users" WHERE "users"."username" = '234234' LIMIT 1
D, [2016-05-18T12:01:24.725087 #454] DEBUG -- : SQL (0.4ms) INSERT INTO "users" ("name", "email", "password_digest", "username", "user_type", "created_at", "updated_at", "activation_digest") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["name", "234234"], ["email", "[email protected]"], ["password_digest", "$2a$10$l3JDATUxIMIKvMIYYtRhQ.AR8GSC3C9ybwXIFjGgU3ORCeUDjtpra"], ["username", "234234"], ["user_type", "Personal Account"], ["created_at", "2016-05-18 09:01:24.549035"], ["updated_at", "2016-05-18 09:01:24.549035"], ["activation_digest", "$2a$10$STp22TuKMbPbn14XXgVJa.yGYd3h9o31xMeEZxcNDsvAJQM4lpQ0."]]
D, [2016-05-18T12:01:24.729336 #454] DEBUG -- : (2.7ms) commit transaction
I, [2016-05-18T12:01:24.751436 #454] INFO -- : Rendered user_mailer/account_activation.html.erb within layouts/mailer (4.2ms)
D, [2016-05-18T12:01:24.751639 #454] DEBUG -- :
UserMailer#account_activation: processed outbound mail in 21.0ms
I, [2016-05-18T12:01:24.751911 #454] INFO -- : Completed 500 Internal Server Error in 296ms
F, [2016-05-18T12:01:24.801486 #454] FATAL -- :
ActionController::UrlGenerationError (No route matches {:action=>"edit", :controller=>"account_activations", :email=>"[email protected].com", :format=>nil, :id=>nil, :locale=>nil} missing required keys: [:id]):
app/views/user_mailer/account_activation.html.erb:9:in `_app_views_user_mailer_account_activation_html_erb___3249946951177976060_70255610070180'
app/mailers/user_mailer.rb:10:in `account_activation'
app/models/user.rb:95:in `send_activation_email'
エラーはそれがリンクとしてid params
アカウント起動コントローラについてのIDを探して編集リンクであることを示します。問題は、私がロケールをルートに配置する前にこの構造が動作していたことです。
ルート;
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
...
resources :account_activations, only: [:edit]
...
end
したがって、私はアカウントの有効化htmlでユーザーIDを送信します。
<%= link_to "Activate", edit_account_activation_url(@user.activation_token,
email: @user.email, id: user.id) %>
リンクが生成されます。
localhost:3000/78y5fzxrFtGzwpr5RHlnCQ/account_activations/7/edit?email=....%40.....com
だから私はここを参照してくださいすることは代わりにトークンを、FR言うことができますし、代わりにIDのトークンのような存在でなければなりませんロケール変数が存在すべきである、ということです。
私はここにそれが既に持っている申し訳ありません;:
localhost:3000/fr/account_activations/78y5fzxrFtGzwpr5RHlnCQ/edit?email=....%40.....com
あなたは
EDITありがとう
class ApplicationController < ActionController::Base
before_filter :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
@locale = params[:locale] || I18n.default_locale
end
def default_url_options(options = {})
{locale: I18n.locale}
end
end
したがって、電子メールのリンクを次のように変更します。
<%= link_to "Activate", edit_account_activation_url(id: @user.activation_token, email: @user.email, locale: "fr") %>
ただし、ロケール変数を電子メールに渡すにはどうすればいいですか?
編集:私は、変数を渡した
: usermailer
def account_activation(user)
@user = user
@locale = I18n.locale
mail to: user.email, subject: "Account activation"
end
は、リンクで呼び出す:
<%= link_to "Activate", edit_account_activation_url(id: @user.activation_token,
email: @user.email, locale: @locale) %>
希望が他の誰かに役立ちます。