Rails 3 UJS干客户端+服务器端表单验证

时间:2010-10-17 05:14:56

标签: ruby-on-rails validation forms ruby-on-rails-3 ujs

使用jQuery进行表单验证就像向字段添加类名一样简单。使用rails进行表单验证就像将条件放入控制器(和/或模型)一样简单。

我认为应该有一种方法来编写验证一次并将它们应用于客户端和服务器端。我一直都喜欢编写自己的javascript,但是如果可以实现这一点,那么使用rails3不引人注目的UJS可能非常值得。

谢谢!

4 个答案:

答案 0 :(得分:2)

您应该考虑创建自己的表单构建器,以自定义form_for的行为。您可以执行一些操作,将类设置为属性上定义的验证名称,并让jQuery将其自身绑定到相应的类名。让我们从表单构建器的外观开始。

class ValidationFormBuilder < ActionView::Helpers::FormBuilder
  def text_field(object_name, method, options = {})
    options[:class] = object_name.class.validators_on(method).map do |k| 
      # Eg: ActiveModel::Validations::PresenceValidator -> presence
      k.to_s.slice(/[^:]+Validator$/).chomp('Validator').downcase
    end.join(' ')
    super(object_name, method, options)
  end
end

您需要设置form_for才能使用ValidationFormBuilder。

<%= form_for @foo, :builder => ValidationFormBuilder do |f| %>
  <%= f.text_field :bar %>
<% end %>

... becomes something like

<form action="/foo" method="post">
  <input type="text" class="presence" name="foo[bar]" id="foo_bar">
</form>

如果您需要更多的类名称灵活性,您可能需要创建一个映射到所需字符串的哈希。

class ValidationFormBuilder < ActionView::Helpers::FormBuilder
  MAPPINGS = {
    ActiveModel::Validations::PresenceValidator => 'text'
  }

  def text_field(object_name, method, options = {})
    options[:class] = object_name.class.validators_on(method).map do |k| 
      MAPPINGS[k]
    end.join(' ')
    super(object_name, method, options)
  end
end

您可以通过在Rails源代码的activemodel/lib/active_model/validations中窥视来查看Rails中包含的完整验证列表。我希望这足以让你开始。

答案 1 :(得分:2)

答案 2 :(得分:0)

您可以使用RJS使用服务器端验证(并且它不依赖于您是否使用UJS):

# create.js.haml
= render :partial => "shared/flash_messages", :locals => { :flash => flash }

- if @message.errors.any?
  $('#reply_message').html('#{escape_javascript(render(:partial => "message_form"))}');
- else
  $('ul.data_grid .list').append('#{escape_javascript(render "message", :message => @message)}');
  $('#reply_message textarea').val('');

答案 3 :(得分:0)