2013-04-10 4 views
3

У меня есть довольно стандартная модель User с дизайном. Администраторы управляются с помощью :admin boolean на модели, и пользователи, которые не являются администраторами, не могут самостоятельно управлять (то есть только администраторы могут вносить изменения в пользователей).Devise: разрешить пользователям только сбросить пароль

Что бы я хотел, это разрешить пользователям сбросить пароль, если они его забудут. Они будут вводить свой адрес электронной почты, а затем будут отправлены по электронной почте токен, который предоставит им доступ, чтобы изменить его. Я начал решение, но я действительно не знаю, как это сделать.

user.rb

class User < ActiveRecord::Base 
    devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable 
    attr_accessor :current_password 
    attr_accessible :name, :password, :password_confirmation, :current_password, :email, :remember_me, :ftp, :colour1, :colour2, :logo, :logo2, :address, :url, :disclosure, :general_advice, :facebook, :twitter, :brand_id, :analytics 
    attr_protected :admin 
    validates_uniqueness_of :email, :ftp 
    belongs_to :brand 
    has_many :docs 
    has_many :orders, :through => :docs 
    has_attached_file :logo 
    has_attached_file :logo2 
end 

class Ability 
    include CanCan::Ability 
    def initialize(user) 
    user ||= User.new #guesting 
    if user.admin? 
     can :manage, :all 
    else 
     can :manage, :recoverable 
    end 
    end 
end 

А вот метод:

def reset 
    @idiot = User.where(:email => params[:email]).first 
    unless @idiot.nil? 
     Notifier.send_reset_notice(@idiot).deliver 
     @idiot.send_reset_password_instructions 
     redirect_to new_user_session_url 
    else 
     redirect_to new_user_session_url, :flash => { :error => "That email address matches no user." } 
    end 
end 

Пользователь получает письмо DEViSE, но нажав на ссылку берет пользователя в корневом каталоге приложения, а не к форма сброса пароля. Я не уверен, как исходить отсюда. Есть предположения? Ура!

UPDATE

Соответствующие маршруты:

devise_for :users, :path => "d" 
devise_scope :user do 
    get '/sign_in' => 'devise/sessions#new' 
    get '/sign_out' => 'devise/sessions#destroy' 
end 
+0

вы должны быть судимы это решение [DEViSE вики] (https: // Г thub.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-edit-their-password)? –

+0

Да, это не работает для моей ситуации. Похоже, что есть проблемы с моими маршрутами или чем-то еще. Я обновлю вопрос с помощью своих маршрутов. –

ответ

3

Во-первых, создать контроллер для ручки Devise :: PasswordsController

class PasswordusersController < Devise::PasswordsController 
    prepend_before_filter :require_no_authentication 
    append_before_filter :assert_reset_token_passed, :only => :edit 

    def new 
    super 
    end 

    def create 
    self.resource = resource_class.send_reset_password_instructions(resource_params) 

    if successfully_sent?(resource) 
     redirect_to root_path, :notice => "Instruction has been send to your email" 
    else 
     respond_with(resource) 
    end 
    end 

    def edit 
    super 
    end 

    def update 
    self.resource = resource_class.reset_password_by_token(resource_params) 

    if resource.errors.empty? 
     resource.unlock_access! if unlockable?(resource) 
     flash_message = resource.active_for_authentication? ? :updated : :updated_not_active 
     set_flash_message(:notice, flash_message) if is_navigational_format? 
     sign_in(resource_name, resource) 
     redirect_to login_path, :notice => "Password has been change" 
    else 
     respond_with resource 
    end 
    end 

    protected 

    def after_sending_reset_password_instructions_path_for(resource_name) 
     root_path 
    end 

    def assert_reset_token_passed 
     super 
    end 

    def unlockable?(resource) 
     super 
    end 

end 

Чем, запустить генерировать представление для завещанию

копию new.html.erb и edit.html.erb от views/devise/passwords до views/passwordusers

на routes.rb вы можете сконфигурировать такие как:

devise_scope :user do 
get '/reset_password' => "passowrdusers#new", :as => :reset_password 
get '/new_password' => "passwordusers#edit", :as => :new_password 
end 

редактировать ссылку на devise/mailer/reset_password_instructions.html.erb

<p><%= link_to 'Change My Password', new_password_path(@resource, :reset_password_token => @resource.reset_password_token) %></p> 

наконец, вид формы входа добавить

<%= link_to "Forgot Password?", reset_password_url(resource_name) %> 

UPDATE

на routes.rb вы можете сконфигурировать такие как:

devise_scope :user do 
get '/reset_password' => "passowrdusers#new", :as => :reset_password 
get '/new_password' => "passwordusers#edit", :as => :new_password 
post '/send_email' => 'passwordusers#create', :as => :create_password 
put '/change' => 'passwordusers#update', :as => :update_password 
end 

на

<%= form_for("user", :url => create_password_path(resource_name), :html => { :method => :post }) do |f| %> 

на views/passwordusers/edit.html.erb

<%= form_for("user", :url => update_password_path(resource_name), :html => { :method => :put }) do |f| %> 
+0

Спасибо за ваш ответ! Это близко, но я получаю некоторые ошибки.Во-первых, созданный URL-адрес выглядит так: 'domain.com/new_password.2?reset_password_token = ...', который не работает. Когда я меняю его на '/ new_password/2? ...', я получаю ошибку «Нет маршрута» [GET] »/ new_password/2». –

+0

в форме 'new.html.erb', такой как' <% = form_for ("user",: url => passwordusers_create_path (resource_name),: html => {: method =>: post}) do | f | %> '? –

+0

Они выглядят следующим образом: '<% = form_for (resource,: as => resource_name,: url => password_path (resource_name),: html => {: method =>: post}) do | f | %> '. Должен ли я изменить их на то, что вы написали? –

Смежные вопросы