我正在使用Sequel,我的模型定义如下:
class A < Sequel::Model
one_to_one :lang, class: ALang, key: :a_id,
graph_join_type: :inner do |ds|
ds.where(ALang__lang: I18n.locale.to_s)
end
delegate :title, :titleSanitized, :description, to: :lang
# ...
end
I18n.lang = :de
A.eager(:lang).all
# block is called ("ds.where(ALang__lang: I18n.locale.to_s)" code)
# database was queried (I can see the query in logs)
I18n.lang = :en
A.eager(:lang).all
# block is not called
# database was queried (I can see the query in logs)
是错误还是功能?或者我做错了什么?
谢谢
答案 0 :(得分:2)
在这种情况下,会热切地评估该块,并缓存生成的数据集。要延迟评估当前区域设置,您需要使用延迟评估:
one_to_one :lang, class: ALang, key: :a_id,
graph_join_type: :inner do |ds|
ds.where(ALang__lang: Sequel.delay{I18n.locale.to_s})
end
我已经更新了Sequel的文档以反映这一点。
答案 1 :(得分:0)
假设您正在说&#34;阻止&#34;你意味着A
class
的身体或者身体内的某些东西,这是完全合理的。类只加载一次(通常,除非猴子修补,但即便如此,#34;加载&#34;是一个值得商榷的术语)。
在这种情况下,A
的正文设置了您正在执行的查询的声明性逻辑。如果您正在与传递给one_to_one
的块进行对话,那么可能Sequel::Model
正在计算其结果并在加载类时将其缓存。
我在这里错过了这个问题吗?
答案 2 :(得分:0)
这是一个特色:
只有在加载类时才会对块进行求值。这就是为什么在ActiveRecord中使用lambdas来定义范围或关联中的变量部分的原因。我不知道Sequel是否也支持查询或关联定义中的lambda。
数据库未被调用两次,因为关联在被检索后被缓存。见Caching in the docs for Sequel::Model