2014-11-21 2 views
0

레일스 메일러를 작동 시키려고하는데 새 사용자를 등록하고 활성화 이메일을 보내려고 할 때 다음과 같은 오류 메시지가 나타납니다. 내가있는 Hartl의 최신 장 10 다음있어이 작동한다 이론에 너무 railstutorial (3 에드.) : 코드의레일에 메일러를 설정하지 못했습니다.

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

app/views/user_mailer/account_activation.html.erb:9:in `_app_views_user_mailer_account_activation_html_erb__1296124105699284853_2236858900' 

app/mailers/user_mailer.rb:6:in `account_activation' 

app/models/user.rb:82:in `send_activation_email' 

app/controllers/users_controller.rb:27:in `create' 

관련 비트은 다음과 같습니다

사용자 모델 :

class User < ActiveRecord::Base 
    attr_accessor :remember_token, :activation_token 
    extend FriendlyId 
    friendly_id :callsign, :use => :slugged 
    has_secure_password 
    before_save do 
    self.email.downcase! 
    self.callsign.downcase! 
    end 
    before_create do 
    :create_activation_digest 
    end 
    validates :name, presence: true, length: { maximum: 50 } 
    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i 
    validates :email, presence: true, 
        format:  { with: VALID_EMAIL_REGEX }, 
        uniqueness: { case_sensitive: false } 
    VALID_CALLSIGN_REGEX = /\A[a-z\d\-.\_]+\z/i 
    validates :callsign, presence: true, 
         length:  { maximum: 20 }, 
         format:  { with: VALID_CALLSIGN_REGEX }, 
         uniqueness: { case_sensitive: false } 
    validates :password, length: { minimum: 6 } 
    validates :slug, presence: true 

    # Returns the hash digest of the given string. 
    def self.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 self.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 

    # Forgets a user. 
    def forget 
    update_attribute(:remember_digest, nil) 
    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 

    # 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 

    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 

end 

사용자 컨트롤러 :

class UsersController < ApplicationController 

    before_action :logged_in_user,  only: [:index, :show, :edit, :update, :destroy] 
    before_action :non_logged_in_user, only: [:new, :create] 
    before_action :correct_user,  only: [:edit, :update] 
    before_action :admin_user,   only: :destroy 

    def index 
    @users = User.paginate(page: params[:page]) 
    end 

    def show 
    @user = User.friendly.find(params[:id]) 
    @page_name = "user_page" 
    end 

    def new 
    @user = User.new 
    end 

    def create 
    @user = User.new(user_params) 
    if @user.save 
     @user.send_activation_email 
     flash[:info] = "Please check your email to activate your account." 
     redirect_to root_url  
    else 
     render 'new' 
    end 
    end # create 

    def destroy 
    @user = User.find(params[:id]) 
    if (current_user != @user) 
     @user.destroy 
     flash[:success] = "User deleted." 
     redirect_to users_url 
    else 
     redirect_to @user, notice: "Suicide is not permitted, admin chappie. Hard cheese." 
    end 
    end 

    def edit 
    @user = User.find(params[:id]) 
    end 

    def update 
    @user = User.find(params[:id]) 
    if @user.update_attributes(user_params) 
     flash[:success] = "Profile updated" 
     redirect_to @user 
    else 
     render 'edit' 
    end 
    end # update 

    private 

    def user_params 
     params.require(:user).permit(:name, :email, :callsign, :password, :password_confirmation) 
    end 

    # Before filters 

    def non_logged_in_user 
     if logged_in? 
     redirect_to root_url, notice: "Nice try pal. You can't create a new user 
             if you're already signed in." 
     end 
    end 

    def correct_user 
     @user = User.find(params[:id]) 
     redirect_to(root_url) unless current_user?(@user) 
    end 

    def admin_user 
     redirect_to(root_url) unless current_user.admin? 
    end 

end 

account_activation.html.erb :

<h1>MySite</h1> 

<p>Hi <%= @user.name %>,</p> 

<p> 
Welcome! Click on the link below to activate your account: 
</p> 

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

user_mailer.rb :

class UserMailer < ActionMailer::Base 
    default from: "[email protected]" 

    def account_activation(user) 
    @user = user 
    mail to: user.email, subject: "Account activation" 
    end 

    def password_reset 
    @greeting = "Hi" 

    mail to: "[email protected]" 
    end 
end 

routes.rb :

Mysite::Application.routes.draw do 

    resources :users 
    resources :account_activations, only: [:edit] 
    root    'static_pages#home' 
    get 'help' => 'static_pages#help' 
    get 'about' => 'static_pages#about' 
    get 'contact' => 'static_pages#contact' 
    get 'signup' => 'users#new' 
    get 'login' => 'sessions#new' 
    post 'login' => 'sessions#create' 
    delete 'logout' => 'sessions#destroy' 

end 

편집 : account_activations_controller.rb :

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] = "Account activated!" 
     redirect_to user 
    else 
     flash[:danger] = "Invalid activation link" 
     redirect_to root_url 
    end 
    end 

end 
+0

이 계정 활성화 컨트롤러를 게시하시기 바랍니다. –

답변

1

나는이를 사용하는 것이 좋습니다 것입니다 당신의 리소스 대신 파일 경로 지정 :

get 'account_activation', "account_activations#edit", :as => :edit_account_activation 

... 비밀 토큰과 이메일 주소 매개 변수를 처리하십시오.

는 지금 문제는 당신이 오류를 찾은 account_activation.html.erb

+0

고맙습니다, 고맙습니다 만 다음 코드를 사용해야합니다 : 'get 'account_activation'=> 'account_activations # edit', : as => : edit_account_activation' 질문은 왜 'edit_account_activation_url (@ user.activation_token, 이메일 : @ user.email) %>'account_activation.html.erb에서 올바른 경로를 만드시겠습니까? 이것은 routes 파일에서'resources : account_activations, only : [: edit]'에 의해 생성 된 edit_account_activation_path에 요청을 보내지 않습니까? – Bazley

+0

Bazley는 경로 도우미를 호출 했음에도 불구하고 routes.rb 파일에 정의되어 있어야합니다. 그렇지 않으면 오류가 발생합니다.라우트 파일에 정의되지 않은 라우트는 뷰에서 작성할 수 없습니다. 다행히 도울 수있어. –

+0

이것은 내가 이해하지 못하는 것입니다 - 원래 코드가 작동해서는 안됩니다? 라우트 파일에 정의되어 있기 때문에 : 코드 : 'resources : account_activations, only : [: edit]' 은 edit_actions 컨트롤러에서 편집 작업을 수행하는 명명 된 경로 edit_account_activation_path를 생성합니까? – Bazley

0

에서 사용하는 경로와 일치하는 컨트롤러 액션을하지 않아도됩니다.

before_create do 
    :create_activation_digest 
end 

그것은해야한다 :

before_create do 
    create_activation_digest 
end 

또는 :

before_create :create_activation_digest 

모범생 오류 문제는 클래스 사용자 코드의이 비트이었다. 모든 사람의 시간을 낭비하는 것에 대해 사과드립니다.

(따라서 코드 : routes.rb에서

resources :account_activations, only: [:edit] 

참으로 올바른 경로를 생성 않습니다)

관련 문제