ActiveRecord Validation: based on attribute or function

I am looking for some clarification about what ActiveRecord is actually doing when it performs validation of an instance of a class that inherits from ActiveRecord::Base.

For the purpose of discussion here is an example (you can assume that bar is a column in the foos table generated by an AR migration)

class Foo < ActiveRecord::Base
 def bar
  read_attribute(:bar).length
 end
end

f = Foo.new
f.bar = 'abcdefg'

f.bar => 7
f.read_attribute(:bar) => 'abcdefg'

What I want to understand is when ActiveRecord calls .valid? (or any method that invokes validation) is f.bar validated, or is f.read_attribute(:bar) validated?

Are there some special cases to the answer? For instance when using the uniqueness validator or a custom validator.

Equally important: when AR writes generates the insert or update statement to write the object to the database are the attribute values persisted, or are the values returned from the functions having the names of the table's columns used?


Interesting question, so I experimented.

Validation for presence is on the accessor method f.bar not on the f.read_attribute(:bar)

However, uniqueness validation will test that a record with bar column value 7 is not in the database, so uniqueness validation will not work as expected.

For uniqueness, you may want to make a custom validation where you test that f.read_attribute(:bar) is not already present (and that if it is present, it's not the same record)

The custom validator is, of course, custom, so you can explicitly use f.bar or f.read_attribute(:bar) depending on which best serves your needs.

链接地址: http://www.djcxy.com/p/49732.html

上一篇: 为什么ActiveRecord在STI模型的类型列中插入NULL?

下一篇: ActiveRecord验证:基于属性或功能