Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Maybe a problem of validates :format #14040

kkzhang opened this Issue · 3 comments

2 participants


I posted on , but didn't resolved. I think it maybe a bug or something:

In my activerecord model:

  validates :achieve_points, :format => { :with=> /\A\d{1,10}\z/, :message => "Only allow 1-10 digits integers"}

In rspec:

r = build(:achieve, :achieve_type_id=>1, :achieve_points => 'a'*5)
expect(r.valid?).to eq(false)

Test not passed,

expected: false
got: true

But other cases is all valid, which means the regualr express is in its position,

it "is invalid when not provided" do
    r = build(:achieve, :achieve_type_id=>1, :achieve_points => nil)
    expect(r.valid?).to eq(false)

it "is invalid when empty" do
    r = build(:achieve, :achieve_type_id=>1, :achieve_points => '')
    expect(r.valid?).to eq(false)

it "is invalid when out of range" do
    r = build(:achieve, :achieve_type_id=>1, :achieve_points => '5'*11)
    expect(r.valid?).to eq(false)

it "is valid when integer in range" do
    r = build(:achieve, :achieve_type_id=>1, :achieve_points => '5'*10)
    expect(r.valid?).to eq(true)

But WHY? Something may be wrnong, but i stuck for a long time.

PS: Rails 4.02, ruby 2.1.0p0, Mac os 10.9


I'm trying change to ruby2.0, rails4.01, but not works at all. Finally i abandon :format, user other validator instead.

validates :achieve_points, :presence=>true,
                          :numericality => {:only_integer => true, :greater_than => 0},
                          :length => {:maximum => 10}

@kkzhang please attach an executable test-case to reproduce the problem. You can use this script as a foundation.

    unless File.exist?('Gemfile')
      File.write('Gemfile', <<-GEMFILE)
        source ''
        gem 'rails', "4.0.2"
        # gem 'arel'
        gem 'sqlite3'

      system 'bundle'

    require 'bundler'

    require 'active_record'
    require 'minitest/autorun'
    require 'logger'

    # This connection will do for database-independent bug reports.
    ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
    ActiveRecord::Base.logger =

    ActiveRecord::Schema.define do

      create_table :wallets do |t|
        t.integer :points

    class Wallet < ActiveRecord::Base
      validates :points, :presence=>true, :format => { :with=> /\A\d{1,10}\z/, :message => "Only allow 1-10 digits integers"}

    describe Wallet do
      it "should be invaid" do>"ffff").valid?.must_equal false



@kkzhang this is due to the fact how Active Record currently turns Strings on Integer columns into 0. You can observe this behavior when you create a new Wallet instance:

Wallet.create(points: "ffff")
# => SQL (0.2ms)  INSERT INTO "wallets" ("points") VALUES (?)  [["points", 0]]

In case of your example, the validation runs agains 0, which matches your format. Also note that validates_format_of is supposed to be used for string columns and not integer columns. There is validates_numericality_of for number based columns.

We are currently working on this conversion behavior as it is related to many similar issues. See #13922 for a proposed solution and links to other related issues. I'm going to close this ticket, as we are already aware of that behavior and there are enough open issues to remind us about it.

@kkzhang thanks for reporting.

@senny senny closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.