2

在我们的 rails 3.2.12 应用程序中,我们希望将一个只读方法注入到 an 的方法中,instance以将列标记为readonly或不标记。理想情况下,我们可以为应用程序中的每readonly一个的所有方法定义一个通用方法。instancemodel

例如,@projectProject model. 中有一个phone#。方法注入后,我们可以在运行时@project评估(真或假)。@project.phone.readonly如果应用程序中有另一个模型,customer我们可以@customer.name.readonly假设@customerinstance.customer

我们在这里感到singleton class并且define_method可能会有所帮助。但我们不太了解它们将如何工作。有人可以阐明这个问题吗?谢谢您的帮助。

4

2 回答 2

1

http://apidock.com/ruby/Object/define_singleton_method阅读此

但我认为这是个坏主意,因为您的某些属性(电话、姓名等)可能是不可变或冻结对象之一,因此会导致 TypeError

例子

 1.9.3p125 :001 > number = 5.34
     => 5.34 
    1.9.3p125 :002 > def number.readonly?
    1.9.3p125 :003?>   true
    1.9.3p125 :004?>   end
    TypeError: can't define singleton method "readonly?" for Float

我建议你考虑下一个界面

@project.readonly?(:name)

还要检查这个 http://apidock.com/rails/ActiveRecord/ReadonlyAttributes/ClassMethods/attr_readonly https://github.com/rails/rails/blob/master/activerecord/lib/active_record/readonly_attributes

它允许您在初始化程序中执行类似的操作

class  ActiveRecord::Base
  def attr_readonly?(attr_name)
     self.class.readonly_attributes.include(attr_name)
  end
end

进而

 class Phone < ActiveRecord::Base
   attr_readonly :phone
 end

如果不需要 attr_readonly 功能,即不允许在创建对象后更改只读属性,您可以像这样创建自己的模块,但使用另一个 class_attribute 变量。

于 2013-03-31T22:06:28.457 回答
1

@user938363 如果您需要定义一次方法从任何实例调用它,那么您应该在Class中定义方法,而不是在单例实例中。

class Float
  def readonly?
    true
  end
end

n = 1.234
n.readonly? # => true
于 2013-04-01T01:50:25.067 回答