如何在Ruby中为模型创建延迟加载的属性?

时间:2011-03-07 16:25:43

标签: ruby-on-rails ruby

我想创建一个延迟加载的属性,在Model上返回一个集合,我该怎么做?

我不想为此创建关联。

所以我希望它返回一个集合,如果集合尚未初始化,然后点击数据库,返回行,然后初始化它。

如果它运行一次,则无需再次运行它,因为下一页请求将重新开始。

2 个答案:

答案 0 :(得分:20)

添加实例属性(例如@my_attribute

然后定义

def my_attribute
  @my_attribute ||= initialize_my_attribute
end

(注意:initialize_my_attribute是您实现的将加载所需值的函数/方法。)

这是如何工作的:该属性以nil值开头(我们没有为其分配任何内容)。对象实例无法直接访问它,因为我们尚未在其上定义属性访问器。相反,我们有一个与属性具有完全相同名称的方法,因此当您调用my_object.my_attribute时,它看起来就像您在实际调用对象实例的方法时访问该属性一样。

该方法会发生什么? ||=简写等同于

@my_attribute = (@my_attribute || initialize_my_attribute)

因此,如果@my_attribute已经有值,则返回该值。否则,@my_attribute将获取一个值(然后返回)。换句话说:该值将在第一次访问时加载@my_attribute(并且仅在第一次加载)。

瞧!延迟加载。

答案 1 :(得分:0)

默认情况下,关联属性是延迟加载的。检查您的日志,以便只有在访问该属性时才能查询对数据库的查询。

我也遇到过这个问题。在我实现了自制的延迟加载功能后,我意识到它们毫无意义。通过添加如上所述的延迟加载器,您可以在内部lazy-loader中添加一个延迟加载器,这会使性能变慢,而不会添加任何值。