Ruby 关联块只调用一次

Ruby 关联块只调用一次,ruby,sequel,Ruby,Sequel,我正在使用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, :d

我正在使用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)
A类
它是bug还是特性?还是我做错了什么


谢谢你

假设你说的“block”是指
A
的主体或所述主体内的某个东西,这是非常有意义的。类只加载一次(通常情况下,除非使用monkey补丁,但即使这样,“加载”也是一个有争议的术语)

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

我是否遗漏了这个问题?

这是一个功能:

加载类时,该块仅计算一次。这就是为什么在ActiveRecord中使用lambdas来定义作用域或关联中的变量部分。我不知道Sequel在查询或关联定义中是否也支持lambda


数据库不会被调用两次,因为关联在检索后会被缓存。请参见

在本例中,将急切地评估块,并缓存结果数据集。要延迟对当前区域设置的评估,需要使用延迟评估:

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

抱歉,我不清楚,我删除了包含
ds.where(ALang\u lang:I18n.locale.to_s)
code.Gotcha,从@spickermann的回答中可以看出我的直觉是正确的。请参阅结尾“如果您谈论的是传递给one-to-one的块,那么很可能Sequel::Model正在计算其结果,并在加载类时缓存它。“好吧,这是可以理解的。但是,如果块定义不能反映动态状态,那么我就看不到在关联中使用块定义的意义。你明白我的意思吗?我相信我做错了什么,但我不知道是什么:(.好的,但为什么在两次调用中都查询数据库?请查看编辑后的问题。非常感谢。您是否在Rails日志或数据库日志中看到查询?Rails日志只告诉您Rails请求了该数据,但不告诉您缓存层是否能够提供该数据。在缓存层中提供查询结果时,您可以将在Rails日志中看到查询,但不会在数据库的日志中看到查询,因为它实际上没有两次为数据库提供工具包。问题不在于缓存数据,而在于缓存数据集以进行关联。现在所有问题都已解决。感谢您抽出时间。