我知道我可以编写attr_accessor:tag_list来为Rails中的对象创建一个虚拟属性tag_list。这允许在对象的表单中有一个tag_list属性。
如果我使用attr_accessor:tag_list,我可以在模型中对tag_list执行操作以从表单中提取和操作数据。
我想知道的是,如何编写一个完全复制attr_accessor默认功能的getter和setter,而不是编写attr_accessor。 EG:
def tag_list
#what goes here
end
仅供参考我尝试过
def tag_list
@tag_list
end
这不起作用。
答案 0 :(得分:66)
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相同的存储空间。对于后者,确实如此。
在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
答案 1 :(得分:9)
使用ActiveRecord时,这是等效的getter和setter版本:
def tag_list
read_attribute(:tag_list)
end
def tag_list=(val)
write_attribute(:tag_list, val)
end
这是你在找什么?
答案 2 :(得分: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