如何在Ruby中为模型创建惰性加载属性?
问题描述:
我想创建一个延迟加载的属性,返回模型上的集合,我该如何做到这一点?如何在Ruby中为模型创建惰性加载属性?
我不想为此创建关联。
所以我希望它返回一个集合,如果集合尚未初始化,然后命中数据库,返回行,然后初始化它。
如果它运行一次,则不需要再次运行它,因为下一个页面请求会启动。
答
添加的实例属性(如@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
中。
瞧!延迟加载。
答
默认情况下,相关属性是延迟加载的。检查你的日志,看看只有在访问属性时才会对数据库进行查询。
我也遇到过这个问题。在我实现了我自制的懒惰加载函数之后,我意识到它们毫无意义。通过添加如上所述的懒加载器,您可以将lazy-loader添加到内部lazy-loader,这会使性能变慢,而不会增加任何值。
你为什么要这样做?这正是一个协会的目标。 – tadman 2011-03-07 16:39:44
@tadman b/c它不适合我的工作,请参阅:http://*.com/questions/5215836/could-i-add-an-association-based-on-another-association – Blankman 2011-03-07 16:59:22