简体   繁体   English

在Ruby on Rails 4上重写属性访问器

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM