Ruby on rails 当提交一个简单的表单来创建新的模型实例时,这是一件非常有趣的事情

Ruby on rails 当提交一个简单的表单来创建新的模型实例时,这是一件非常有趣的事情,ruby-on-rails,Ruby On Rails,我正在开发一个Rails v2.3.2应用程序 我有一个带有验证的模型: class Person < ActiveRecord::Base validates_presence_of :name, :email # Please notice this method def pwd=(pwd) encrypted_pwd = pwd + randn(127) self.password = encrypted_pwd end end 视

我正在开发一个Rails v2.3.2应用程序

我有一个带有验证的模型

class Person < ActiveRecord::Base 
  validates_presence_of :name, :email

  # Please notice this method
  def pwd=(pwd)
      encrypted_pwd = pwd + randn(127)
      self.password = encrypted_pwd  
  end
end 
视图
视图/persons/new.html.erb
):

我还尝试了从Rails控制台创建和保存对象,如:

Person.new(:name=>'John', :email=>'john@gmail.com', :pwd=>'test')
因此:

1。为什么如果表单中的所有字段都填写了值,我可以成功创建一个模型实例,但是当我离开
name
email
时,我得到了错误
,但密码(pwd)字段输入值为空


2。为什么我没有收到错误消息,抱怨
名称
电子邮件
不应为空?

原因是您的模型缺少
pwd的属性读取器(getter)

下面是正在发生的事情:

由于需要
name
email
(由
提供,验证:name,:email
的存在),当您没有输入它们并提交表单时,会发生错误,表单会再次呈现,视图希望填充
pwd
字段,但您尚未定义它,您会收到错误消息:
未定义#
的方法“pwd”

因此,您可以向
Person
类添加如下getter:

def pwd
  "" # or whatever you like
end
你的表格应该会再次生效。如果希望模型在发生错误时记住未加密的密码,则可以使用类似以下内容:

def pwd=(pwd)
  @pwd = pwd
  encrypted_pwd = pwd + randn(127)
  self.password = encrypted_pwd
end

def pwd
  @pwd || ""
end

要回答第二个问题,您没有得到验证错误,因为您没有在视图中检查它们。验证失败时,错误消息将添加到与您试图保存的对象关联的错误哈希中。要可选地显示它们,请在视图中添加类似的内容:

<% form_for :person, @person, :url => persons_url, :html=>{:method=>:post} do |f| %>
  <% if @person.errors.any? %>
    <ul id="errors">
    <% @person.errors.full_messages.each do |error| %>
      <li>
        <%= error %>
      </li>
    <% end %>
    </ul>
  <% end %>

Rest of your form goes here...
persons_url,:html=>{:method=>:post}do | f |%>
你剩下的表格在这里。。。
那么,为什么我第一次加载new.html.erb页面时,它不抱怨“:pwd”??如果我填写表单中的所有字段,我甚至可以创建一个person实例,你能解释一下吗?因为在你的
new
操作中,你没有创建
person
的实例,在你看来,表单中的所有字段都是空的。但是在
create
操作中,您的have
@person
(没有
pwd
方法),它被发送到视图以在表单中呈现。
def pwd
  "" # or whatever you like
end
def pwd=(pwd)
  @pwd = pwd
  encrypted_pwd = pwd + randn(127)
  self.password = encrypted_pwd
end

def pwd
  @pwd || ""
end
<% form_for :person, @person, :url => persons_url, :html=>{:method=>:post} do |f| %>
  <% if @person.errors.any? %>
    <ul id="errors">
    <% @person.errors.full_messages.each do |error| %>
      <li>
        <%= error %>
      </li>
    <% end %>
    </ul>
  <% end %>

Rest of your form goes here...