正如标题所说,我试图在 Rails 4 模型中重用我的自定义验证方法。我有类似的情况:
class Resource < ActiveRecord::Base
RESOURCE_TYPE = ["webpage", "image", "video", "paragraph"]
validates :type, presence: true
validate :always_invalid, if: :webpage?
validate :always_invalid, if: :image?
def always_invalid
binding.pry
errors.add(:data, "Invalid")
end
# methods for type checking
RESOURCE_TYPE.each do |res_type|
define_method("#{res_type}?") { self.type == res_type }
end
end
我希望这将无法验证 type 为webpage
或的对象image
。但是,当我尝试运行时,只有image
for 类型的对象无效。
> a
=> #<Resource id: nil, type: "webpage", data: {:url=>"http://morar.net/forest"}, created_at: nil, updated_at: nil>
> a.webpage?
=> true
> a.valid?
=> true
> b
=> #<Resource id: nil, type: "image", data: {:url=>"http://powlowski.info/colleen.langworth/nulla.png"}, created_at: nil, updated_at: nil>
> b.image?
=> true
> b.valid?
From: /home/mark/source/summer/app/models/resource.rb @ line 13 Resource#always_invalid:
12: def always_invalid
=> 13: binding.pry
14: errors.add(:data, "Invalid")
15: # return false
16: end
> exit
=> false
所以似乎只有最后一个 validate: 语句有效。
更改 2 validate 语句的顺序可以扭转局面:类型webpage
的对象无效,而image
for 类型的对象则不会。
如果你能解释为什么会发生,那就太好了。
谢谢
PS:我的架构,以防您需要它:
create_table "resources", force: true do |t|
t.string "type"
t.json "data"
t.datetime "created_at"
t.datetime "updated_at"
end