Ruby on rails 在实例';s范围

Ruby on rails 在实例';s范围,ruby-on-rails,ruby,Ruby On Rails,Ruby,我想创建一些类似于ActiveRecord验证的东西:在验证之前做。。。结束。我不确定如何从给定的块中引用类实例的属性。有什么想法吗 class Something attr_accessor :x def self.before_validate(&block) @before_validate_block = block end before_validate do self.x.downcase end def validate! # how sh

我想创建一些类似于ActiveRecord验证的东西:
在验证之前做。。。结束
。我不确定如何从给定的块中引用类实例的属性。有什么想法吗

class Something
 attr_accessor :x

 def self.before_validate(&block)
   @before_validate_block = block
 end

 before_validate do
  self.x.downcase
 end

 def validate!
   # how should this method look like? 
   # I would like that block would be able to access instance attributes
 end
end

这可以通过使用或来实现


这可以通过使用或来实现


@3limin4t0r的答案涵盖了在普通ruby中很好地模仿行为。但是,如果您在Rails中工作,您不需要仅仅因为不使用ActiveRecord就重新发明轮子

您可以使用在任何普通的旧ruby对象中定义回调:

class Something
  extend ActiveModel::Callbacks
  define_model_callbacks :validate, scope: :name

  before_validate do
    self.x.downcase
  end

  def validate!
    run_callbacks :validate do
      # do validations here
    end
  end
end 
就功能而言,它会让你在这里得到的任何答案都大吃一惊。它允许在事件之前、之后和周围定义回调,并处理每个事件的多个回调

如果验证是您真正想要的,尽管您可以只包括
ActiveModel::validations
,它提供了所有验证,当然除了由ActiveRecord定义的
验证的唯一性之外


ActiveModel::Model
包括构成rails模型API的所有模块,如果您要声明虚拟模型,这是一个不错的选择。

@3limin4t0r的答案涵盖了在纯ruby中很好地模拟行为。但是,如果您在Rails中工作,您不需要仅仅因为不使用ActiveRecord就重新发明轮子

您可以使用在任何普通的旧ruby对象中定义回调:

class Something
  extend ActiveModel::Callbacks
  define_model_callbacks :validate, scope: :name

  before_validate do
    self.x.downcase
  end

  def validate!
    run_callbacks :validate do
      # do validations here
    end
  end
end 
就功能而言,它会让你在这里得到的任何答案都大吃一惊。它允许在事件之前、之后和周围定义回调,并处理每个事件的多个回调

如果验证是您真正想要的,尽管您可以只包括
ActiveModel::validations
,它提供了所有验证,当然除了由ActiveRecord定义的
验证的唯一性之外

ActiveModel::Model
包括组成rails模型API的所有模块,如果您要声明虚拟模型,这是一个不错的选择。

这怎么样

class Something
  attr_accessor :x

  class << self
    attr_reader :before_validate_blocks
    def before_validate(&block)
      @before_validate_blocks ||= []
      @before_validate_blocks << block
    end
  end

  def validate!
    blocks = self.class.before_validate_blocks
    blocks.each {|b| instance_eval(&b)}
  end
end

Something.before_validate do
  puts x.downcase
end

Something.before_validate do
  puts x.size
end

something = Something.new
something.x = 'FOO'
something.validate! # => "foo\n3\n"
分类
属性存取器:x
班级这个怎么样

class Something
  attr_accessor :x

  class << self
    attr_reader :before_validate_blocks
    def before_validate(&block)
      @before_validate_blocks ||= []
      @before_validate_blocks << block
    end
  end

  def validate!
    blocks = self.class.before_validate_blocks
    blocks.each {|b| instance_eval(&b)}
  end
end

Something.before_validate do
  puts x.downcase
end

Something.before_validate do
  puts x.size
end

something = Something.new
something.x = 'FOO'
something.validate! # => "foo\n3\n"
分类
属性存取器:x

这看起来真的很棒。我已经在使用ActiveModel::Validations,并且我看到已经包含回调。但我在使用时看到了奇怪的错误:
验证:test\u字段,presence:true命名错误:未定义的方法
在#
的_validate'之前。知道为什么会出现这个错误吗?@knagode你能提出一个新问题吗?我真的需要看一个代码示例才能有所帮助。我在这里创建了一个虚拟类&问题:这看起来真的很棒。我已经在使用ActiveModel::Validations,并且我看到已经包含回调。但我在使用时看到了奇怪的错误:
验证:test\u字段,presence:true命名错误:未定义的方法
在#
的_validate'之前。知道为什么会出现这个错误吗?@knagode你能提出一个新问题吗?我真的需要看一个代码示例才能有所帮助。我在这里创建了虚拟类和问题: