Войти или Зарегистрироваться (Ruby on rails) - PullRequest
1 голос
/ 03 января 2011

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

Форма входа:

<% 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 %>

Я добавил необходимые проверки в мою модель пользователя:

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

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

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

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

Заранее спасибо!

1 Ответ

1 голос
/ 03 января 2011

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

# 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 %>

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

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