让我们说用户提交表单。其中一个字段无效,因此表单会重新呈现。在重新呈现表单的过程中:我检查该属性的提交值是否无效。如果是这样:那么显示带有一些附加文本的无效数据输入。
这是我到目前为止所拥有的。它很接近,但没有完全运作:
<%= form_for(blog) do |f| %>
<div class="field">
<%= f.label :age %>
<% if f.object.age %>
<% if f.object.errors.include?(:age) %>
<%= f.text_field :age, value: "Submitted: #{f.object.age} was bad" %>
<% else %>
<%= f.text_field :age %>
<% end %>
<% else %>
<%= f.text_field :age %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
所以我说:“嘿Rails:如果用户已提交此表单,和用户为此age
属性提交的值无效,则重新呈现输入中提交的值以及一些其他文本。“
我遇到的问题是它不会正确显示错误输入。例如:如果用户在输入字段中输入“abcd”,那么当表单在验证失败时重新呈现时,输入字段应该说:“已提交:abcd是坏的”。相反,它说“提交:0很糟糕”。
我很接近。最终的问题是:为什么显示0
?为什么不显示"abcd"
?接下来的问题是:“如何让它显示"abcd"
?
这是因为我有以下验证吗? :
validates :age, numericality: true
如果是这样:我如何进行验证以确保它是一个数字,还重新显示用户输入的值?
答案 0 :(得分:0)
这是失败的,因为您在插值字符串中调用f.object.age
,而不是提交的值。
由于您正在验证年龄的数字,因此'abcd'
输入将永远不会通过验证,因此永远不会保存。
因此,当您在该对象上调用.age
时,您只获得默认值,或者通过验证并保存的最后一个值。 1}}字符串永远不会被保存。
显示错误的更简单方法是:
'abcd'
您还可以尝试添加自定义错误消息:
f.object.errors.full_messages_for(:age)
答案 1 :(得分:0)
这很有效。只需从params
哈希中获取提交的值:
<div class="field">
<%= f.label :age %>
<% if f.object.age %>
<% if f.object.errors.include?(:age) %>
<%= f.text_field :age, value: "Submitted #{params[:blog][:age]} is bad" %>
<% else %>
<%= f.text_field :age %>
<% end %>
<% else %>
<%= f.text_field :age %>
<% end %>
</div>
f.object.age
似乎不起作用,因为age
属性属于integer
类型。因为:在age
属性的writer方法中:
def age=(value)
...
end
在该setter中的某个地方可能发生的是rails试图将提交的值转换为:to_i
。当您对字符串执行to_i
时,它会返回0
,因此当您尝试f.object.age
时,它将返回0
,因为作者尝试转换字符串。
另一个棘手的问题是text_field
方法。 Rails在那里有一些魔力。例如:如果没有任何特殊内容:以下将成功显示提交的值而不是0
:
<%= f.text_field :age %>
因此,在text_field
方法中的某个位置,rails会查看age
的该属性是否无效,如果是,则指定为提交的value
价值。
如果没有深入研究rails源代码,很难说text_field
如何确定该属性是否先前已提交,以及提交的值是否无效。因此:如果在rails源代码中挖了一个,我相信一旦你弄清楚text_field
如何显示提交的值(例如'abcd'
而不是转换后的值),你可以清理上面的条件。设定者(例如:'0'
)。
尽管如此:上面的代码可以正常工作并完成所需的工作。