2013-03-03 3 views
2

У меня есть модель пользователя с атрибутами имени и пароля. Когда пользователь нажимает «Редактировать», я хочу, чтобы только поле имени редактировалось и проверялось, но не поле пароля. И наоборот, когда пользователь нажимает «Сбросить пароль». Я думаю, что моя основная проблема заключается в том, как отключить проверку пароля во время редактирования поля имени и как отключить проверку имени во время редактирования пароля?Как обновить два разных атрибута на двух разных страницах?

edit.html.erb

<%= form_for @user, html: { class: "form_settings" } do |f| %> 
    <%= render 'shared/error_messages', object: f.object %> 
    <p><span><%= f.label :name %></span> 
    <%= f.text_field :name %> 
    </p> 

    <p style="padding-top: 15px"><span>&nbsp;</span> 
    <%= f.submit "Submit", class: "submit" %> 
    </p> 
<% end %> 

reset_password.html.erb

<%= form_for @user, html: { class: "form_settings" } do |f| %> 
    <%= render 'shared/error_messages', object: f.object %> 
    <p><span><%= label_tag :old_password, "Current Password" %></span> 
    <%= password_field_tag :old_password %> 
    </p> 

    <p><span><%= f.label :password %></span> 
    <%= f.password_field :password %> 
    </p> 

    <p><span><%= f.label :password_confirmation %></span> 
    <%= f.password_field :password_confirmation %> 
    </p> 

    <p style="padding-top: 15px"><span>&nbsp;</span> 
    <%= f.submit "Submit", class: "submit" %> 
    </p> 
<% end %> 

users_controller.rb

def update 
    @user = User.find(params[:id]) 
    if params[:old_password] 
    if @user.authenticate(params[:old_password]) 
     @user.update_attributes(password: params[:user][:password]) 
     flash[:success] = "Password has been updated" 
     redirect_to @user 
    else 
     flash.now[:error] = "Current password is incorrect" 
     render :reset_password 
    end 
    elsif @user.update_attributes(params[:user]) 
    flash[:success] = "User name updated" 
    redirect_to @user 
    else 
    render :edit 
    end 
end 

Моя другая проблема заключается в том, что проверка пароля и пароля_подтверждения не работает. Это то, что я имею в модели:

validates :password, presence: true, confirmation: true 

UPDATE Есть пароль для сброса и проверки работы с этим кодом:

def update 
    @user = User.find(params[:id]) 
    if params[:old_password] 
    if @user.authenticate(params[:old_password]) 
     if params[:user][:password] == params[:user][:password_confirmation] 
     @user.update_attributes(password: params[:user][:password]) 
     flash[:success] = "Password has been updated" 
     redirect_to @user 
     else 
     flash.now[:error] = "Passwords don't match" 
     render :reset_password 
     end 
    else 
     flash.now[:error] = "Current password is incorrect" 
     render :reset_password 
    end 
    elsif @user.update_attributes(params[:user]) 
    flash[:success] = "User name updated" 
    redirect_to @user 
    else 
    render :edit 
    end 
end 

Но это кажется слишком сложным для меня. Кто-нибудь видит более легкое решение?

Но у меня все еще есть проблема с редактированием поля имени. Он говорит, что пароль не может быть пустым.

ответ

1

Не следует смешивать название редактирования и сброс пароля на такое же действие.

Создать одно действие, которое будет обновлять атрибуты вашего пользователя, password поле не должно быть белый список с attr_accessible

Создать еще одну акцию, которая будет иметь дело с сброса пароля.

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

def reset_password 
    if params[:old_password] && @user.authenticate(params[:old_password]) 
    if params[:user][:password] == params[:user][:password_confirmation] 
     @user.password = params[:user][:password] 
     flash[:success] = "Password has been updated" 
     redirect_to @user 
    else 
     flash.now[:error] = "Passwords don't match" 
     render :reset_password 
    end 
    else 
    flash.now[:error] = "Current password is incorrect" 
    render :reset_password 
    end 
end 

Таким образом, каждое действие имеет свою семантическую роль.

Btw, я надеюсь, что вы используете что-то вроде bcrypt для хранения пароля.

+0

По какой-то причине действие обновления вызывается, когда я пытаюсь сбросить пароль, как это. – mikeglaz

+0

Вы используете форму? Вы должны указать каждую кнопку на другое действие. – Intrepidd

+0

Да, вот и все. Не знал, что вы можете применить действие в form_for. Я, наконец, в такой момент, когда я понимаю ответы программистов Rails. благодаря – mikeglaz

0

Фигурные это ... но это выглядит любопытное уродливые: логика проверки

def update 
    @user = User.find(params[:id]) 
    if params[:old_password] 
    if @user.authenticate(params[:old_password]) 
     if params[:user][:password] == params[:user][:password_confirmation] 
     @user.update_attributes(password: params[:user][:password]) 
     flash[:success] = "Password has been updated" 
     redirect_to @user 
     else 
     flash.now[:error] = "Passwords don't match" 
     render :reset_password 
     end 
    else 
     flash.now[:error] = "Current password is incorrect" 
     render :reset_password 
    end 
    elsif params[:user][:name].blank? 
    flash[:error] = "Name can't be blank" 
    render :edit 
    else 
    @user.update_attribute(:name, params[:user][:name]) 
    flash[:success] = "User name updated" 
    redirect_to @user 
    end 
end 
1

Move для моделирования и держать контроллер в чистоте.

validates :password, presence: true, confirmation: true, if: password?, on: :update 
validates :name, presence: true, if: name?, on: :update 

Это необходимо, когда вы создаете запись. Просто добавьте on: :create

validates :password, presence: true, confirmation: true, on: :create 
validates :name, presence: true, on: :create 

И изменить ваш контроллер, как это,

def update 
    @user = User.find(params[:id]) 
    @user.authenticate(params[:old_password]) if params[:old_password] 
    return redirect_to @user, notice: "Sucessfully updated" if @user.update_attributes(params[:user]) 
    render Rails.application.routes.recognize_path(request.referer)[:action] 
end 

Б визуализация идеи по этой ссылке: Render the action that initiated update

+0

Прошу прощения, я не понимаю, что если: пароль? и если: name? делать. Являются ли методы, которые мне нужно построить? – mikeglaz

+0

Хммм. Это методы rails, если пароль имеет какое-то значение, он вернет true, иначе false, то же самое относится и к имени. Когда u обновляется через пароль сброса Первая проверка будет выполнена, когда U обновит имя, только в этом случае будет выполняться вторая операция validaion. –

+0

Я думаю, что это должно быть с двоеточием: пароль? – mikeglaz

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