[英]Overriding attribute accessors on Ruby on Rails 4
I have a Restriction model that represent a formula
. 我有一个表示formula
的限制模型。 The field formula
is a string that at runtime is evaluated. 字段formula
是在运行时评估的字符串。 This field can't be accessed from outside for security reasons so I'am trying to override the accessors. 出于安全原因,无法从外部访问此字段,因此我尝试覆盖访问器。
class Restriction < ActiveRecord::Base
belongs_to :indicator
RESTRICTION_TYPES = {
less_than: "IND<X",
greater_than: "X<IND",
between: "X<IND && IND<Y"
}
def evaluate(number)
f = formula.gsub("IND", "#{number}")
eval(f)
end
def create_formula(type_name, arg)
if(type_name == :between)
f = RESTRICTION_TYPES[:between].gsub("X", "#{arg[0]}").gsub("Y", "#{arg[1]}")
else
f = RESTRICTION_TYPES[type_name].gsub("X", "#{arg}")
end
formula = f
end
private
def formula= f
write_attribute(:formula, f)
end
def formula
read_attribute(:formula)
end
def [](value)
super[value]
end
def []=(key, value)
super[key] = value
end
end
In rails console: 在Rails控制台中:
Loading development environment (Rails 4.0.0)
2.0.0p247 :001 > r = Restriction.new
=> #<Restriction id: nil, formula: nil, indicator_id: nil, created_at: nil, updated_at: nil, state: nil>
2.0.0p247 :002 > r.create_formula(:between, [1,2])
=> "1<IND && IND<2"
2.0.0p247 :003 > r.evaluate 1.5
NoMethodError: undefined method 'gsub' for nil:NilClass
2.0.0p247 :004 > r
=> #<Restriction id: nil, formula: nil>
formula
is not change the value. formula
不改变值。 What am I doing wrong? 我究竟做错了什么?
PS: You can see that I have also overriden [](value)
and []=(key, value)
. PS:您可以看到我也重写了[](value)
和[]=(key, value)
。 This is due to my previous question 这是由于我之前的问题
Rails internally relies on the hash like access methods for reading and writing attributes. Rails在内部依赖像访问方法一样的哈希来读取和写入属性。 By making them private you wanted to restrict the access of [] and []= to from within the object only. 通过将它们设为私有,您只想将[]和[] =的访问限制为仅从对象内部进行。 But you destroyed the method, because you are using super the wrong way. 但是您破坏了该方法,因为您使用超级方法的方式错误。 When calling super
you are not getting the super object of this class, but the super method, the current method overrides. 调用super
您不会获得此类的super对象,但会获得super方法(当前方法会覆盖)。 Thus change it like this and it should work: 因此,像这样更改它,它应该可以工作:
def [](value)
super(value)
end
def []=(key, value)
super(key, value)
end
PS: Overriding a method for declaring it private is overkill in Ruby. PS:在Ruby中,重写一种声明为私有的方法是过大的。 You can simply declare it private with 您可以简单地将其声明为私有
private :[], []=
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.