【问题标题】:Rails 3 UJS dry Client + Server Side form validationRails 3 UJS 干式客户端+服务器端表单验证
【发布时间】:2010-10-17 05:14:55
【问题描述】:

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

我认为应该有一种方法可以编写一次验证并将它们应用于客户端和服务器端。我一直是编写自己的 javascript 的粉丝,但是有了 rails3 的隐蔽性,如果 UJS 可以做到这一点,它在这里可能非常值得。

谢谢!!

【问题讨论】:

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


    【解决方案1】:

    您应该考虑创建自己的表单构建器来自定义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 中包含的完整验证列表。我希望这足以让你开始。

    【讨论】:

      【解决方案2】:
      【解决方案3】:

      您可以使用 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('');
      

      【讨论】:

        【解决方案4】:

        是否进行 JS 验证,包括一些用于验证唯一性的简洁的 ajax。

        https://github.com/bcardarella/client_side_validations

        http://railscasts.com/episodes/263-client-side-validations

        【讨论】:

          猜你喜欢
          • 2011-10-17
          • 2013-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-19
          • 2011-06-21
          • 1970-01-01
          相关资源
          最近更新 更多