我正在努力解决Hartl教程的一个问题(我已经添加了自己的自定义需求,即用户属于公司,创建表单是#new公司。)现在一切正常,比如密码重置等。除了一件事就是activation_token方法。
现在我已经尝试调试以确定问题的确切行,这就是这个:
@user.activation_token
当我尝试仅为登录用户打印时,它是空白的。现在我得到的准确错误是:
No route matches {:action=>"edit", :controller=>"account_activations", :email=>"ex@ex.ex", :id=>nil} missing required keys: [:id]
请求参数如下:
"company"=>{"users_attributes"=>{"0"=>{"first_name"=>"demo", "last_name"=>"demo", "email"=>"ex@ex.ex", "password"=>"demodemo"}}, "name"=>"demo"}
并且错误发生在:
<%= link_to "Activate", edit_account_activation_url(@user.activation_token, email: @user.email) %>
我的User.rb:
class User < ActiveRecord::Base
attr_accessor :remember_token, :activation_token, :reset_token
before_create :create_activation_digest
...
class << self
# Returns the hash digest of the given string.
def 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 new_token
SecureRandom.urlsafe_base64
end
end
private
# 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
现在它可以在我的测试中获取ID时执行以下操作:
def account_activation
user = User.first
user.activation_token = User.new_token
UserMailer.account_activation(user)
end
我的companycontroller #crera看起来像这样:
def create
@company = Company.new(company_params)
if @company.save
user = @company.users.first
user.send_activation_email
flash[:info] = "registerd and email sent"
redirect_to root_url
else
flash.now[:danger] = 'issues with creating user.'
render 'new'
end
end
我的公司参与:
def company_params
params.require(:company).permit(:name, users_attributes: [:id, :first_name, :last_name, :email, :password])
end
路线:
Rails.application.routes.draw do
get 'password_resets/new'
get 'password_resets/edit'
root 'welcome#index'
get 'company/users' => 'companies#users'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :companies
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
end
注意:用户确实成功保存,公司也是如此。当我取消注释时,我也能够获得一般用户信息.activation_token我可以看到我能够从我的控制台获取电子邮件中的@ user.first_name等。
在图片上你可以看到@ user.activation_token是nil,但它找到了@user对象。答案 0 :(得分:1)
根据您的屏幕截图,问题不在于您的activation_token
方法,因为这似乎是创建和调用的方法。
问题是,如果该路径需要edit_activations_path
,则@user.activation_token
使用id
(不包括id
)填充<%= link_to "Activate", edit_account_activation_url @user %>
。
您应将其更改为:
id
根据您的路由(我在下面进行了改进),以及将对象传递给路由操作的Rails标准做法意味着您应该传递整个对象,并让Rails确定具体细节。
您的错误表明它未被传递@user
- 向我们显示如果您传递@user.activation_token
对象而不是activation_token
,它将使Rails能够使用它。
唯一需要注意的是,您可能会在email
控制器中呼叫Activations
和 #config/routes.rb
root 'welcome#index'
resource :company, only: [] do
get :users, on: :collection
end
resources :companies, :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :sessions, only: [:new, :create, :destroy], path_names: { new: "login", create: "login", destroy: "logout" }
。如果是这种情况,您需要重新设计路线以分别接受令牌和电子邮件(下方):
您可以对代码进行一些改进:
-
您的路线可以更有效率:
account_activations
现在,需要注意的重要事项是Rails
资源将成为标准id
资源...... IE将期望activation_token
制定路线。典型ID将是对象的primary_key,您要使用<%= link_to "Activate", edit_account_activation_url(id: @user.activation_token, email: @user.email) %>
。要解决此问题,您应该使用以下内容:
:id
这仍然会接受params :email
(必填)和#app/controllers/activations_controller.rb
class ActivationsController < ApplicationController
def edit
token = params[:id]
email = params[:email]
end
end
,但会填充您需要的数据,允许您使用:
User
-
模型调用def create_activation_digest
activation_token = class.new_token
activation_digest = class.digest(activation_token)
end
两次。你应该拨打以下电话:
/*
* Remember that NULL + any string = NULL.
* Provide the concat var with a default value.
*/
DECLARE @ConCat VARCHAR(255) = '';
DECLARE @SampleTable TABLE
(
Value VARCHAR(5)
)
;
-- Populate the sample table.
INSERT INTO @SampleTable (Value)
VALUES
('a'),
('b'),
('c')
;
-- Concatenate the values into one string.
SELECT
@ConCat = @ConCat + Value
FROM
@SampleTable
;
-- Return the concatenated string
SELECT
@ConCat
;