2011-01-02 3 views
1

Я работаю над приложением Ruby on Rails (2.3.x), и я хочу создать форму, которая позволит пользователю войти в систему или зарегистрироваться. Я хочу сделать это в той же форме. У меня есть функция JS, которая заменяет элементы формы, как это:Войти или Зарегистрироваться (Ruby on rails)

Войти Форма:

<% form_for @user do |f| %> 
<div id="form"> 
    <%= f.label :email, "E-mail" %> 
    <%= f.text_field :email %> 

    <%= f.label :password, "Password" %> 
    <%= f.password_field :password %> 

    <%= link_to "I don't have an account, "#", :id => "changeForm"%> 
    <%= f.submit "Login" %> 
</div> 
<% end %> 

Идентификатор «changeForm» запускает функцию JS, которая изменяет форму элементов. Так что, если вы нажмете на URL-HTML выглядит следующим образом:

<% form_for @user do |f| %> 
<div id="form"> 
    <%= f.label :name, "Name" %> 
    <%= f.text_field :name %> 

    <%= f.label :email, "E-mail" %> 
    <%= f.text_field :email %> 

    <%= f.label :password, "Password" %> 
    <%= f.password_field :password %> 

    <%= f.label :password_confirmation, "Password confirmation" %> 
    <%= f.password_field :password_confirmation %> 

    <%= link_to "I do have an account, "#", :id => "changeForm"%> 
    <%= f.submit "Register" %> 
</div> 
<% end %> 

Я добавил neccesary валидаций к моей модели пользователя:

class User < ActiveRecord::Base 
    attr_reader :password 
    validates_presence_of :name, :email, :password 
    validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i 
    validates_confirmation_of :password 

Но что происходит, когда вы заполняете электронную почту/пароль, Вы получаете ошибки, которые отсутствуют в этом имени, и что поля пароля не подтверждены. Так что я мог бы сделать некоторые неприятные программирования в моей модели пользователя, как это:

#if password_conf or the name are present the user has tried to register... 
if params[:user][:password_confirmation].present? || params[:user][:name].present? 
    #so we'll try to save the user 
    if @user.save 
    #if the user is saved authenticate the user 
    current_session.user = User.authenticate(params[:user]) 
    #if the user is logged in? 
    if current_session.user.present? 
     flash[:notice] = "succesvully logged 
     redirect_to some_routes_path 
    else 
     #not logged in... 
     flash[:notice] = "Not logged in" 
     render :action => "new"    
    end 
    else 
    #user not saved 
    render :action => "new" 
    end 
else 
    #So if the params[:user][:password_confirmation] or [:user][:name] weren't present we geuss the user wants to login... 
    current_session.user = User.authenticate(params[:user]) 
    #are we logged_in? 
    if current_session.user.present? 
     flash[:notice] = "Succesvully logged in" 
     redirect_to some_routes_path 
    else 
     #errors toevoegen  
     @user.errors.add(:email, "The combination of email/password isn't valid") 
     @user.errors.add(:password," ") 
     render :action => "new" 
    end 
end 
end 

Без валидаций этого (IMHO грязного кода и не должен быть в контроллере) работает. Но я хочу использовать методы validates_presence_of, и я не хочу удалять «соглашения над конфигурациями» в лицо.

Так еще одна вещь, я попробовал добавляет скрытое поле в форме:

#login form 
    <%= f.hidden_field :login, :value => true %> 
    # and ofcourse set it to false if we want to register. 

И тогда я хотел бы использовать метод: before_validation

before_validation_on_create do |user| 
    if params[:user].login == true #throws an error i know... 
     validates_presence_of :email, :password 
     validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i 
    else 
    validates_presence_of :name, :email, :password 
    validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i 
    validates_confirmation_of :password   
    end 
end 

Но это не работает, потому что Я не могу получить доступ к параметрам. И логин не является атрибутом для объекта пользователя. Но я подумал, что таким образом я могу проверить параметры электронной почты и пароля, если пользователь хочет войти в систему. И все остальные attrs, если пользователь хочет зарегистрироваться.

Так что все, о чем я мог думать, не работает, как я хочу, чтобы он работал. Поэтому моя основная цель:

1 форма для входа/регистрации с использованием методов проверки в пользовательской модели. Поэтому, если мы хотим войти в систему, но не заполнять какую-либо информацию => дать ошибки проверки. И если пользователь хочет войти в систему, но комбинация по электронной почте/паролю doens't соответствует «@ user.errors.add (: email,« комбинация не найдена в db ... »)». И то же самое касается регистра пользователя ...

Заранее благодарен!

+0

Почему вы хотите сделать это по тому же маршруту? – stef

+1

Я согласен с Стефом. Вы можете войти в систему или зарегистрироваться на той же странице, но при этом формы должны быть представлены на разных контроллерах или действиях. –

ответ

1

Вы должны указать каждую форму для соответствующего действия контроллера:

# Registration form 
<% form_for @user, :url => users_path do |f| %> 
... 
<% end %> 

# Login form, non-RESTful action 
<% form_for @user, :url => login_users_path do |f| %> 
... 
<% end %> 

Это предполагает, что вы есть login действия в вашем UsersController, но если вы хотите иметь специальный контроллер управления свои сессии:

# Use SessionsController (Sessions#Create) to create a new user session 
<% form_for @user, :url => sessions_path do |f| %> 
... 
<% end %> 
+1

Хороший ответ, но в будущем, пожалуйста, направляйте пользователей на использование более простых помощников маршрутизации, таких как 'session_path', которые они должны генерировать в' config/routes.rb'. –

+0

Хорошее предложение. Обновлен мой ответ. –

+0

Спасибо, что получилось работать! Человек-мужчина, я чувствую себя действительно немым прямо сейчас ... но после кодирования 8 часов вы начинаете делать ошибки ... –

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