开发者

Debugging client_side_validations using Rails 3.1

I am having trouble getting any of it to work. This is my first attempt. After a while, I did see some change on the page when tabbing out of the password field, but no error message shows up. Here are the relevant files. The idea is to disallow free email domains like aol, yahoo, gmail, etc. Please help me if you see a bug that's keeping it from working. Thank you so much.

errors on submit but not in real time– http://i.stack.imgur.com/x5qUR.png

[Update]

throw Error("Sprockets::FileNotFound: 
couldn't find file 'public/javascripts/rails.validations.custom.js'\n  
(in /Users/jess/Sites/[appname]/app/assets/javascripts/application.js:10)")

user.rb

class User < ActiveRecord::Base
  attr_accessible :email, :password, :password_confirmation
  has_secure_password
  validates :password, presence: { :on => :create }
  #validates :email, presence: { :on => :create }
  validates :email, email_format: true
  has_many :companies
end

routes.rb

[AppName]::Application.routes.draw do
  get "home/index"
  resources :users
  resource :sessions
  root :to => 'users#new'
end

rails.validations.custom

clientSideValidations.validators.local["email_format"] = function(element, options) {
  if (/^.+(@aol\.com)$/i.test(element.val())) {
    return options.message;
  }
}

application.js

//= require jquery
//= require jquery_ujs
//= require rails.validations
//= require rails.validations.custom
//= require_tree .

en.yml

en:
  errors:
    messages:
      email_format: "is not formatted properly"

User#new

%h2 Sign up

= form_for @user, validate: true do |f|
  - if @user.errors.any?
    .error_messages
      %h3 Form is invalid
      %ul
        - @user.errors.full_messages.each do |message|
          %li= message
  .field
    = f.label :email
    = f.text_field :email

  .field
    = f.label :password
    = f.password_field :password

  .field
    = f.label :password_confirmation
    = f.password_field :password_confirmation

  .actions= f.submit

client_side_validations.rb

# ClientSideValidations Initializer

require 'client_side_validations/simple_form' if defined?(::SimpleForm)
require 'client_side_validations/formtastic'  if defined?(::Formtastic)

# Uncomment the following block if you want each input field to have the validation messages attached.
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  unless html_tag =~ /^<label/
    %{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first开发者_开发知识库}</label></div>}.html_safe
  else
    %{<div class="field_with_errors">#{html_tag}</div>}.html_safe
  end
end

user_spec.rb (all tests pass)

require 'spec_helper'

describe User do
  before :all do
    User.delete_all
  end
  describe 'Association' do
    it { should have_many(:companies) }
  end

  describe 'Database Columns' do
    it { should have_db_column(:email).of_type :string }
    it { should have_db_column(:password_digest).of_type :string }
  end

  describe 'Indexed Columns' do
    it { should have_db_index(:email) }
  end

  describe 'Valid Records' do
    user = Factory(:user, email: "foo@example.com", password: 'foobar')
    User.find_by_email(user.email).try(:authenticate, user.password).should == user

    it 'should not allow free email domains' do
      user.email = 'foo@aol.com'
      user.should_not be_valid
    end
  end
end

lib/email_format_validator

class EmailFormatValidator < ActiveModel::EachValidator
  def validate_each(object, attribute, value)
    if value =~ /^.+(@aol\.com)$/i
      object.errors.add(attribute, :email_format, options)
    end
  end
end

application.rb

require File.expand_path('../boot', __FILE__)
require 'rails/all'

Bundler.require(:default, Rails.env) if defined?(Bundler)

module [AppName]
  class Application < Rails::Application

    # TODO perhaps dated // http://mikbe.tk/2011/02/10/blazingly-fast-tests/
    if Rails.env.test? 
      initializer :after => :initialize_dependency_mechanism do 
        ActiveSupport::Dependencies.mechanism = :load 
      end 
    end

    # load lib/
    config.autoload_paths += %W(#{config.root}/lib)
    config.autoload_paths += Dir["#{config.root}/lib/**/"]

    config.time_zone = 'Central Time (US & Canada)'

    # Configure the default encoding used in templates for Ruby 1.9.
    config.encoding = "utf-8"

    # Configure sensitive parameters which will be filtered from the log file.
    config.filter_parameters += [:password]

    # Enable the asset pipeline
    config.assets.enabled = true

    config.generators do |g|
      g.test_framework :rspec, :views => false, :fixture => true
      g.fixture_replacement :factory_girl, :dir => 'spec/factories'
      g.form_builder :simple_form
      g.template_engine :haml
    end
  end
end


domain_validator.js.coffee

invalid_domains = [
"@myway.com",
"@mail.com" ] # two, for example, out of about 1,000

domains_joined = invalid_domains.join('|')
domains_pattern = new RegExp("^.+(#{domains_joined})$", "i")

clientSideValidations.validators.local["email_domain"] = (element, options) ->
  if (domains_pattern.test(element.val())) 
    options.message()

lib/email_domain_validator.rb

   class EmailDomainValidator < ActiveModel::EachValidator
      INVALID_DOMAINS = %w( 
         @myway.com
         @mail.com ) # two, for example

      def validate_each(object, attribute, value)
        if value =~  /^.+(#{INVALID_DOMAINS.join('|')})$/i
          object.errors.add(attribute, :email_domain, options)
        end
      end
    end

I also didn't have the right error message. Now I do (email_domain):

config/locales/en.yml

en:
  errors:
    messages:
      email_format: "is not formatted properly"
      email_domain: "this email provider is not allowed" # tada!
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜