在Ruby on Rails中向ActiveRecord实例添加验证回调

时间:2012-08-07 14:05:23

标签: ruby-on-rails activerecord refactoring

我们的ActiveRecord模型有许多不幸使用网络的验证。例如,它使用Facebook API来验证给定的Facebook ID属性。我想将这些验证移出模型,因此它们只在特定的上下文中运行,而不是在Factory Girl的测试中创建的。它还需要以兼容ActiveAdmin的方式完成。

我的想法是将方法提取到模块,并让该模块适当地扩展AR实例。

module ArtistConnectionValidations
  def self.inject_to(record)
    record.extend self
    record.class_eval do
      before_validation :validate_facebook_name
    end
  end

  def validate_facebook_name
    # Contact Facebook API
  end
end

在使用继承资源的ActiveAdmin中:

controller do  # Executes in controller context
  def resource
    ArtistConnectionValidations.inject_to(Artist.find(params[:id]))
  end
end

不幸的是,这些验证不会被调用,因为它们被添加到实例的单例类中,并且#valid?方法回调没有看到它们。各种其他策略导致它被添加到基类,感染整个系统。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我不确定这是否适合你。 但为什么不创建一个子类?

如果我在这里正确理解你需要什么,我认为它会使代码和用法更清晰。

#artist.rb
class Artist < ActiveRecord::Base
end

#artist_with_validations.rb
class ArtistWithValidations < Artist
  before_validation :validate_facebook_name

  def validate_facebook_name
    # Contact Facebook API
  end
end

然后,您可以使用这两个模型中的一个,具体取决于您是否希望用户使用或不使用验证。