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!
精彩评论