在Ruby on Rails中重写setter方法的正确方法是什么? [英] What is the right way to override a setter method in Ruby on Rails?

查看:86
本文介绍了在Ruby on Rails中重写setter方法的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Ruby on Rails 3.2.2,我想知道以下内容是否是正确"/正确"/确定"方式来覆盖我的class属性的setter方法.

I am using Ruby on Rails 3.2.2 and I would like to know if the following is a "proper"/"correct"/"sure" way to override a setter method for a my class attribute.

attr_accessible :attribute_name

def attribute_name=(value)
  ... # Some custom operation.

  self[:attribute_name] = value
end

上面的代码似乎按预期工作.但是,我想知道,通过使用上面的代码,将来我是否会遇到问题,或者至少会遇到Ruby on Rails我应该期望"/可能会发生"的问题.如果那不是重写setter方法的正确方法,那么正确的方法是什么?

The above code seems to work as expected. However, I would like to know if, by using the above code, in future I will have problems or, at least, what problems "should I expect"/"could happen" with Ruby on Rails. If that isn't the right way to override a setter method, what is the right way?

注意:如果我使用代码

attr_accessible :attribute_name

def attribute_name=(value)
  ... # Some custom operation.

  self.attribute_name = value
end

我收到以下错误:

SystemStackError (stack level too deep):
  actionpack (3.2.2) lib/action_dispatch/middleware/reloader.rb:70

推荐答案

============================== ======================================== 更新:2017年7月19日

=========================================================================== Update: July 19, 2017

现在导轨文档还建议像这样使用super:

Now the Rails documentation is also suggesting to use super like this:

class Model < ActiveRecord::Base

  def attribute_name=(value)
    # custom actions
    ###
    super(value)
  end

end

============================================== ==============================

原始答案

如果要在通过模型访问时覆盖表的列的setter方法,则可以采用这种方法.

If you want to override the setter methods for columns of a table while accessing through models, this is the way to do it.

class Model < ActiveRecord::Base
  attr_accessible :attribute_name

  def attribute_name=(value)
    # custom actions
    ###
    write_attribute(:attribute_name, value)
    # this is same as self[:attribute_name] = value
  end

end

请参见覆盖默认值访问器在Rails文档中.

See Overriding default accessors in the Rails documentation.

因此,您的第一种方法是重写Ruby on Rails模型中列设置器的正确方法. Rails已经提供了这些访问器,以访问表的列作为模型的属性.这就是我们所谓的ActiveRecord ORM映射.

So, your first method is the correct way to override column setters in Models of Ruby on Rails. These accessors are already provided by Rails to access the columns of the table as attributes of the model. This is what we call ActiveRecord ORM mapping.

还请记住,模型顶部的 attr_accessible与访问器无关.它具有完全不同的功能(请参见

Also keep in mind that the attr_accessible at the top of the model has nothing to do with accessors. It has a completely different functionlity (see this question)

但是在纯Ruby中,如果您为一个类定义了访问器,并且想覆盖setter,则必须使用这样的实例变量:

But in pure Ruby, if you have defined accessors for a class and want to override the setter, you have to make use of instance variable like this:

class Person
  attr_accessor :name
end

class NewPerson < Person
  def name=(value)
    # do something
    @name = value
  end
end

一旦您知道attr_accessor的作用,这将更容易理解.代码attr_accessor :name等效于这两种方法(getter和setter)

This will be easier to understand once you know what attr_accessor does. The code attr_accessor :name is equivalent to these two methods (getter and setter)

def name # getter
  @name
end

def name=(value) #  setter
  @name = value
end

第二种方法也会失败,因为在该方法中调用同一方法attribute_name=时,它将导致无限循环.

Also your second method fails because it will cause an infinite loop as you are calling the same method attribute_name= inside that method.

这篇关于在Ruby on Rails中重写setter方法的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆