0

我建立了一个search模型,并希望至少填写一个字段。我发现了一个有助于验证的问题Rails: how to require at least one field not be blank。(我尝试了所有答案,但 Voyta 的似乎是最好的。)

验证工作正常,除非我想通过attr_accessoror重新定义 getter/setter attr_writer。(我在表单上有需要作为验证之外的虚拟属性。)为了找出问题所在,我使用常规属性进行了测试item_length。如果我添加attr_accessor :item_length,验证将停止工作。所以,我想问题是如何在不使用点符号的情况下读取属性的值。由于验证使用字符串,我不能使用正常的阅读方式。

这是一个片段:

if %w(keywords 
      item_length 
      item_length_feet 
      item_length_inches).all?{|attr| read_attribute(attr).blank?}
    errors.add(:base, "Please fill out at least one field")
  end

就像我说的那样,虚拟属性(length_inches 和 length_feet)根本不起作用,而普通属性(length)起作用,除非我重新定义了 getter/setter。

4

2 回答 2

7

您应该将 read_attribute 视为读取 Active Record 列的私有方法。否则,您应该始终直接使用阅读器。

self.read_attribute(:item_length) # does not work
self.item_length # ok

由于您试图动态调用它,您可以使用通用 ruby​​ 方法public_send来调用指定的方法

self.public_send(:item_length) # the same as self.item_length
于 2012-08-25T23:29:41.307 回答
6

如评论中所述,使用send

array.all? {|attr| send(attr).blank?}

对于那些想知道send在这种情况下是否可以的人,是的,它是:对象调用它自己的实例方法。

Butsend是一个锋利的工具,因此无论何时与其他对象一起使用,请确保将其公共 api 与public_send

于 2012-08-25T23:31:06.823 回答