验证form_for标签中不存在的存在

时间:2010-01-27 02:27:52

标签: ruby-on-rails

这是我第一次在rails应用程序上进行验证。我看到很多教程让它看起来很简单。我不知道为什么我不能让它工作。 以下是我的设置。

Controller Admin(action = login)

  def login
    session[:user_id] = nil
    if request.post?
      @user = User.authenticate(params[:userId], params[:password])
      if true
        session[:user_id] = @user.user_id
        flash.now[:notice] = "Login Successful"
        redirect_to(:controller => "pages", :action => "mainpage")
      else
        flash.now[:notice] = "Invalid user/password combination"
      end
    end
  end

因此,第一次用户进入管理员/登录时,他们只会看到下面的表格

login.erb.html

<% form_for :user do |f| %>
  <p><label for="name">User ID:</label> 
    <%= f.text_field :userid %>
  </p>
  <p><label for="password">Password:</label>
    <%= f.password_field :password%>
  </p>
  <p style="padding-left:100px">
    <%= submit_tag 'Login' %>
  </p>
<% end %>

我的用户模型:

class User < ActiveRecord::Base
  validates_presence_of :userid, :password
  def self.authenticate(userid, password)
    user = self.find_by_userid_and_password(userid, password)
    user
  end
end

我的数据库中userId和密码的实际字段名称:userid password

我期待的行为是,当用户没有在字段中输入任何内容并且只需单击提交时。它会告诉他们userid和密码是必填字段。但是,这不会发生

从控制台我可以看到消息:

>> @user = User.new(:userid => "", :password => "dsf")
=> #<User id: nil, userid: "", password: "dsf", created_at: nil, updated_at: nil>
>> @user.save
=> false
>> @user.errors.full_messages
=> ["Userid can't be blank"]

所以错误就在我的表单提交...

更新:验证只在您保存对象时发生....这里我没有保存任何内容。那么在这种情况下我必须进行javascript验证吗?

2 个答案:

答案 0 :(得分:0)

这是if true行。将其更改为

if @user = User.authenticate(params[:userId], params[:password])

@user = User.authenticate(params[:userId], params[:password])
if @user
  ...
end

我还会在失败案例中添加redirect_to login_path

您还可以减少身份验证方法:

def self.authenticate(userid, password)
  find_by_userid_and_password(userid, password)
end

答案 1 :(得分:0)

事实证明,这里有几个问题,我会尽力覆盖它们。让我们从你的模型开始:

class User < ActiveRecord::Base
  validates_presence_of :userid, :password

  def self.authenticate(userid, password)
    self.find_by_userid_and_password(userid, password)
  end
end

验证不会用于登录,仅用于创建和更新用户记录。已修剪身份验证,因为ruby会自动返回方法中的最后一个计算值。

接下来,您的控制器的登录操作:

def login
  session[:user_id] = nil
  if request.post?
    if @user = User.authenticate(params[:userId], params[:password])
      session[:user_id] = @user.user_id
      flash[:notice] = "Login Successful"
      redirect_to(:controller => "pages", :action => "mainpage")
    else
      flash.now[:error] = "Invalid user/password combination"
    end
  end
end

请注意,我们不会在重定向上使用flash.now - flash.now仅在您不重定向时才会阻止显示消息两次。

最后,您不应该使用form_for,因为这不是一种宁静的资源形式。您不是在创建或编辑用户,因此请改用form_tag:

<% form_tag url_for(:controller => :users, :action => :login), :method => :post do %>
  <%= content_tag(:p, flash[:error]) if flash[:error] %>

  <p><label for="name">User ID:</label> 
    <%= text_field_tag :userid %>
  </p>
  <p><label for="password">Password:</label>
    <%= password_field_tag :password%>
  </p>
  <p style="padding-left:100px">
    <%= submit_tag 'Login' %>
  </p>
<% end %>

这将做你想要的。这是一个很好的学习练习,但是如果你在生产应用程序中认真对待用户身份验证,请检查诸如restful_authentication或clearance之类的rails插件,以更复杂(和RESTful)的方式为您执行此操作。

相关问题