我可以从复杂查询中检索带有Sequel的对象,该查询将结果限制为单个表中的字段吗?

时间:2012-11-16 16:57:15

标签: ruby sequel

我有一个模型,其行总是要根据另一个关联模型中的值进行排序,我认为实现它的方法是在模型中使用set_dataset。这导致查询结果作为哈希而不是对象返回,因此在迭代数据集时,不能使用类中的任何方法。

我基本上有两个班级

class SortFields < Sequel::Model(:sort_fields)
    set_primary_key :objectid
end

class Items < Sequel::Model(:items)
    set_primary_key :objectid
    one_to_one :sort_fields, :class => SortFields, :key => :objectid
end

一些背景故事:数据从遗留系统导入到mysql中。根据一些复杂的规则,sort_fields中的值是根据多个其他关联表(一些一对多,一些多对多)计算出来的。可能的解决方案是将sort_fields中的值添加到items(我希望将导入的数据与计算数据分开,但我不必这样做)。首先,我只是想了解你可以在多大程度上使用数据集并仍然获得对象而不是哈希。

如果我将数据集设置为对items中的字段进行排序,就像这样

class Items < Sequel::Model(:items)
    set_primary_key :objectid
    one_to_one :sort_fields, :class => SortFields, :key => :objectid
    set_dataset(order(:sortnumber))
end

然后将期望的子句添加到生成的SQL中,例如:

>> Items.limit(1).sql
=> "SELECT * FROM `items` ORDER BY `sortnumber` LIMIT 1"

并且查询仍返回对象:

>> Items.limit(1).first.class
=> Items

如果我通过相关字段订购它......

class Items < Sequel::Model(:items)
    set_primary_key :objectid
    one_to_one :sort_fields, :class => SortFields, :key => :objectid
    set_dataset(
        eager_graph(:sort_fields).
        order(:sort1, :sort2, :sort3)
    )
end

......我得到哈希

?> Items.limit(1).first.class
=> Hash

我首先想到的是,这是因为sort_fields中的所有字段都包含在结果中,如果只选择items中的字段,我会再次获得Items个对象:

class Items < Sequel::Model(:items)
    set_primary_key :objectid
    one_to_one :sort_fields, :class => SortFields, :key => :objectid
    set_dataset(
        eager_graph(:sort_fields).
        select(:items.*).
        order(:sort1, :sort2, :sort3)
    )
end

生成的SQL就是我所期望的:

>> Items.limit(1).sql
=> "SELECT `items`.* FROM `items` LEFT OUTER JOIN `sort_fields` ON (`sort_fields`.`objectid` = `items`.`objectid`) ORDER BY `sort1`, `sort2`, `sort3` LIMIT 1"

它返回与set_dataset(order(:sortnumber))版本相同的行但它仍然不起作用:

>> Items.limit(1).first.class
=> Hash

在我将排序字段添加到items表之前,它们都可以在同一个模型中幸福地生活,有没有办法告诉Sequel在想要返回哈希时返回对象?

1 个答案:

答案 0 :(得分:1)

如果您使用#eager_graph,则必须使用#all代替#each来检索结果,以便处理图表(因为您无法在没有所有实例的情况下急切加载前面),或者使用eager_each插件(这会使#each在内部调用#all