我想创建一个延迟加载的属性,在Model上返回一个集合,我该怎么做?
我不想为此创建关联。
所以我希望它返回一个集合,如果集合尚未初始化,然后点击数据库,返回行,然后初始化它。
如果它运行一次,则无需再次运行它,因为下一页请求将重新开始。
答案 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中添加一个延迟加载器,这会使性能变慢,而不会添加任何值。