2015-10-11 31 views
1

我正在努力處理Hartl教程的一個問題(我添加了自己的自定義需求,即用戶屬於公司,創建窗體是公司#新)。現在一切正常,如密碼重置等。除了一件事是activation_token方法。hartl教程第10章 - 無法找到ID

現在我試着調試靜下心來,這是問題的確切行,它是這一個:

@user.activation_token 

當我嘗試打印出來只是一般的登錄用戶是空白。現在準確的錯誤我得到的是:

No route matches {:action=>"edit", :controller=>"account_activations", :email=>"[email protected]", :id=>nil} missing required keys: [:id] 

請求參數如下:

"company"=>{"users_attributes"=>{"0"=>{"first_name"=>"demo", "last_name"=>"demo", "email"=>"[email protected]", "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#創建看起來像這樣:

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 

我公司PARAMS:

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等。

on the picture you can see @user.activation_token is nil, but it finds the user object

上,你可以看到,@ user.activation_token爲零的圖片,但它發現了@user對象。

+0

請顯示您的'company_params'。我想你可能會錯過允許用戶在那裏使用'id'。 – IngoAlbers

+0

好吧,我已更新以包含我的公司參數。不過,我認爲這個問題可能與activation_token –

+0

有關,你可以在哪裏調用你的'create_activation_digest'方法? – IngoAlbers

回答

1

問題不在於你的activation_token方法,因爲這似乎是根據你的屏幕截圖創建和調用的。

的問題是你填充edit_activations_path@user.activation_token(其中不包括id),當該路徑需要id

您應將其更改爲:

<%= link_to "Activate", edit_account_activation_url @user %> 

根據你的路由(我已經低於改善),並通過對象路由行動的Rails的標準做法意味着你應該通過整個對象,並讓Rails確定具體細節。

您的錯誤指出它的id未被傳遞 - 向我們顯示如果您通過@user對象而不是@user.activation_token,它將使Rails具有使用它的能力。

唯一需要注意的是,您可能會在您的Activations控制器中呼叫activation_tokenemail。如果是這樣的話,你需要重新修改你的路由接受令牌和電子郵件分別爲(如下圖):


有許多改進,你可以讓你的代碼:

-

你的路線可製成高效得多:

#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資源... IE將期望id制定路線。典型的ID將是對象的primary_key,您想要使用activation_token。爲了解決這個問題,你應該使用下列內容:

<%= link_to "Activate", edit_account_activation_url(id: @user.activation_token, email: @user.email) %> 

這將仍然接受PARAMS爲:id(需要)和: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 
相關問題