首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >hartl教程第10章-找不到ID

hartl教程第10章-找不到ID
EN

Stack Overflow用户
提问于 2015-10-11 19:59:14
回答 1查看 116关注 0票数 1

我正在努力解决Hartl教程的一个问题(我已经添加了自己的自定义需求,即用户属于公司,创建表单是company#new)。现在一切都正常了,比如密码重置等等,除了一件事就是activation_token方法。

现在,我已经尝试调试,以深入到确切的行,这是问题所在,这是一个:

代码语言:javascript
复制
 @user.activation_token

当我尝试只为登录用户打印出来时,它是空白的。现在我得到的准确错误是:

代码语言:javascript
复制
No route matches {:action=>"edit", :controller=>"account_activations", :email=>"ex@ex.ex", :id=>nil} missing required keys: [:id]

请求参数如下:

代码语言:javascript
复制
"company"=>{"users_attributes"=>{"0"=>{"first_name"=>"demo", "last_name"=>"demo", "email"=>"ex@ex.ex", "password"=>"demodemo"}}, "name"=>"demo"}

这些错误发生在:

代码语言:javascript
复制
<%= link_to "Activate", edit_account_activation_url(@user.activation_token, email: @user.email) %>

我的User.rb:

代码语言:javascript
复制
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,并执行以下操作:

代码语言:javascript
复制
  def account_activation
    user = User.first
    user.activation_token = User.new_token
    UserMailer.account_activation(user)
  end

我的companycontroller#create看起来是这样的:

代码语言:javascript
复制
  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

我公司的员工:

代码语言:javascript
复制
  def company_params
    params.require(:company).permit(:name, users_attributes: [:id, :first_name, :last_name, :email, :password])
  end

路线:

代码语言:javascript
复制
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是零,但它找到@user对象。

EN

回答 1

Stack Overflow用户

发布于 2015-10-12 11:10:11

问题不在于您的activation_token方法,因为根据屏幕截图,这似乎是创建和调用的。

问题是,当路径需要edit_activations_path时,您正在使用@user.activation_token (不包括id)填充id

你应该把它改为:

代码语言:javascript
复制
<%= link_to "Activate", edit_account_activation_url @user %>

根据您的路由(我在下面对其进行了改进),Rails将对象传递到路由操作的标准实践意味着您应该传递整个对象,并让Rails来确定具体内容。

您的错误声明没有传递的是id --告诉我们如果您传递了@user对象,而不是@user.activation_token,它将使Rails能够使用它。

这里唯一的警告是,您可能在您的activation_token控制器中调用Activationsemail。如果是这样的话,您需要重新调整路由以分别接受令牌和电子邮件(如下所示):

您可以对代码进行一些改进:

--

你的路线可以更有效率:

代码语言:javascript
复制
 #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会制定路线。典型ID将是对象的primary_key,您希望使用activation_token。要解决这个问题,您应该使用以下方法:

代码语言:javascript
复制
<%= link_to "Activate", edit_account_activation_url(id: @user.activation_token, email: @user.email) %>

这仍然会接受params作为:id (必需)和:email,但是将填充所需的数据,允许您使用:

代码语言:javascript
复制
#app/controllers/activations_controller.rb
class ActivationsController < ApplicationController
   def edit
     token = params[:id]
     email = params[:email]
   end
end

--

该模型两次调用User。您应该调用以下命令:

代码语言:javascript
复制
def create_activation_digest
  activation_token  = class.new_token
  activation_digest = class.digest(activation_token)
end
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33069502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档