我创建了一个用户模型,当用户注册时,会发送电子邮件确认邮件。但是当我将locale添加到我的rails应用程序时,它开始出错。
这是user#create action;
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的一部分
# 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
最后,account_activation.html.erb
<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) %>
最后,来自控制台的错误;
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"=>"234@sdf.com", "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('234@sdf.com') 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", "234@sdf.com"], ["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=>"234@sdf.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
所以我在这里看到的是,而不是令牌应该有locale变量,让我们说fr,而不是id应该有像这样的令牌;
localhost:3000/fr/account_activations/78y5fzxrFtGzwpr5RHlnCQ/edit?email=....%40.....com
谢谢
修改
我已经抱歉了;
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") %>
它的工作正常但是,如何将locale变量传递给电子邮件?
修改
我已经传递了一个变量: 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) %>
希望帮助别人。
答案 0 :(得分:1)
您仍然需要在路由中明确设置区域设置,请参阅此question,因此在ApplicationController中包含类似的内容:
def set_locale
I18n.locale = params[:locale] || session[:locale] || I18n.default_locale
session[:locale] = I18n.locale
end
def default_url_options(options={})
logger.debug "default_url_options is passed options: #{options.inspect}\n"
{ locale: I18n.locale }
end
现在,当您使用url helpers时,将自动合并locale选项。