RubyMoney/money-rails — pull request #212 by JuanitoFatas (2014-07-30 15:17:48+00:00)
Title: Possible bug of subunit validation.

Hello money-rails, I think there maybe a bug about numericality validation.

Given:

#### Model

```ruby
class Ticket < ActiveRecord::Base
monetize :price_cents, numericality: { :greater_than => 0 }
end
```

#### db/schema.rb

```ruby
ActiveRecord::Schema.define(version: 20140730065406) do
create_table "tickets", force: true do |t|
t.string "name"
t.integer "price_cents", default: 0, null: false
t.string "price_currency", default: "USD", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
end
```

#### spec/factories/ticket.rb

```ruby
FactoryGirl.define do
factory :ticket do
end
end
```

When I run spec below:

```
describe Ticket do
context 'possible money-rails bug' do
it 'build' do
build_ticket = FactoryGirl.build(:ticket)
expect(build_ticket.valid?).to be_falsey
end

it 'create' do
create_ticket = FactoryGirl.create(:ticket)
expect(create_ticket.valid?).to be_falsey
end
end
end
```

I got:

```
rspec spec/models/ticket_spec.rb
FF

Failures:

1) Ticket possible money-rails bug build
Failure/Error: expect(build_ticket.valid?).to be_falsey
expected: falsey value
got: true
# ./spec/models/ticket_spec.rb:7:in `block (3 levels) in '

2) Ticket possible money-rails bug create
Failure/Error: expect(create_ticket.valid?).to be_falsey
expected: falsey value
got: true
# ./spec/models/ticket_spec.rb:12:in `block (3 levels) in '

Finished in 0.0248 seconds (files took 2.47 seconds to load)
2 examples, 2 failures
```

Both tickets are valid. But they should both be invalid because I have specified `:greater_than => 0`.

That's because my ticket price has a default value of `0`. And it decides when validation happens according to is there a subunit change.

```ruby
# https://github.com/RubyMoney/money-rails/blob/master/lib/money-rails/active_model/validator.rb

subunit_attr = record.class.monetized_attributes[attr.to_sym]
return unless record.changed_attributes.keys.include? subunit_attr
```

This line should be removed:

```ruby
return unless record.changed_attributes.keys.include? subunit_attr
```

After removal of the line above, when I run the spec again, I got:

```
rspec spec/models/ticket_spec.rb
.F

Failures:

1) Ticket possible money-rails bug create
Failure/Error: create_ticket = FactoryGirl.create(:ticket)
ActiveRecord::RecordInvalid:
Validation failed: Price must be greater than 0
# ./spec/models/ticket_spec.rb:11:in `block (3 levels) in '

Finished in 0.02213 seconds (files took 2.12 seconds to load)
2 examples, 1 failure
```

Which should be the expected behaviour.

All the code to reproduce it I put it in this sample app:

https://github.com/JuanitoFatas/money-rails-subunit