关联块只被调用一次

Association block is called only once

我正在使用 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)

这是错误还是功能?还是我做错了什么?

谢谢

假设当您说 "block" 时,您指的是 A class 的主体或所述主体内的某物,这是完全有道理的。 类 只加载一次(通常,除非猴子修补,但即使这样 "loading" 也是一个有争议的术语)。

A 的主体,在本例中,设置了您正在执行的查询的 声明性 逻辑。如果您正在谈论传递给 one_to_one 的块,则可能 Sequel::Model 正在计算其结果并在加载 class 时缓存它。

我是不是漏掉了问题?

这是一项功能:

当加载 class 时,该块仅被评估一个。这就是为什么在 ActiveRecord 中使用 lambda 来定义作用域或关联中的变量部分的原因。我不知道 Sequel 是否也支持查询或关联定义中的 lambda。

数据库没有被调用两次,因为关联在被检索后被缓存。参见 Caching in the docs for Sequel::Model

在这种情况下,块被急切地评估,结果数据集被缓存。要延迟对当前语言环境的评估,您需要使用延迟评估:

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 的文档以反映这一点。