25

我知道我可以编写 attr_accessor :tag_list 来为 Rails 中的对象创建一个虚拟属性 tag_list。这允许在对象的表单中有一个 tag_list 属性。

如果我使用 attr_accessor :tag_list 我可以在模型中对 tag_list 执行操作以从表单中提取和操作数据。

我想知道的是,我将如何编写一个 getter 和 setter 来完全复制 attr_accessor 的默认功能,而不是编写 attr_accessor。例如:

def tag_list
    #what goes here
end

仅供参考我已经尝试过

 def tag_list
     @tag_list
 end

这不起作用。

4

3 回答 3

69

attr_accessor是一个内置的 Ruby 方法,在上下文 ActiveRecord 中没有特殊含义。attr_accessor :tag_list基本上相当于这段代码:

# getter
def tag_list
  @tag_list
end

# setter
def tag_list=(val)
  @tag_list = val
end

然而,在 ActiveRecord 模型中,您可能想要这样的东西:

def tag_list
  self[:tag_list]
end

def tag_list=(val)
  self[:tag_list] = val
end

有一点点不同:第一种方法obj[:tag_list]不使用与 getter 和 setter 相同的存储空间。对于后者,它确实如此。

getter/setter 概念的解释

在 Ruby 中,下面两行代码是等价的

thing.blabla
thing.blabla()

两者都调用blabla对象的方法thing并计算在该方法中计算的最后一个表达式。这意味着,在上述 getter 方法的情况下,您也不需要return语句,因为该方法只返回方法中的最后一个表达式(@tag_list实例变量的值)。

此外,这两行代码是等效的:

thing.blabla=("abc")
thing.blabla = "abc"

两者都调用blabla=对象的方法thing。带有字符的特殊名称=可以像任何其他方法名称一样使用。

有时称为属性的事实实际上是简单的方法,您还可以在返回或接受它们之前对值使用一些特殊的逻辑转换。例子:

def price_in_dollar
  @price_in_euro * 0.78597815
end

def price_in_dollar=(val)
  @price_in_euro = val / 0.78597815
end
于 2012-01-08T02:09:33.110 回答
10

使用 ActiveRecord 时,这是等效的 getter 和 setter 版本:

def tag_list
  read_attribute(:tag_list)
end

def tag_list=(val)
  write_attribute(:tag_list, val)
end

这是你要找的吗?

于 2012-01-08T02:13:26.250 回答
0
Notice the code below is in the [Helpers] path. Helpers are now included for                            
all [Controllers] to work from when instantiated.

module SettergettersHelper

#TODO Wayne 
mattr_accessor :nameport
#TODO Wayne Mattingly the code below was replaced BY ABOVE 
#TODO and not depricatable RAILS 4.2.3

# def nameport
#   @nameport 
# end

# def nameport=(nameport)
#   @nameport = nameport 
#end
end

*Getter from Accounts Controller:*
def index
   @portfolio_name = nameport     
end
*Setter from Portfolio Controller:*
def show
    @portfolio_name = @portfolio_name.portfolio_name #from database call
    SettergettersHelper.nameport =  @portfolio_name # set attribute
end
于 2015-08-31T01:11:04.407 回答