Ruby 删除数据集筛选器的一部分
如果应用了多个筛选器,如何创建一个新的数据集来删除或覆盖其中一个现有筛选器 ds1=DB[:x]。过滤器A:1,b:2 => ds2=ds1.filtera:42我想更改一个,而不是添加另一个 =>Ruby 删除数据集筛选器的一部分,ruby,sequel,Ruby,Sequel,如果应用了多个筛选器,如何创建一个新的数据集来删除或覆盖其中一个现有筛选器 ds1=DB[:x]。过滤器A:1,b:2 => ds2=ds1.filtera:42我想更改一个,而不是添加另一个 => DataSetUnfilted方法删除所有过滤器,例如,它删除b=2。虽然在上述简单的情况下很容易重新添加,但在我的实际情况下,这会导致代码重复。您可以将选择规则存储在哈希中,然后重新使用哈希: require 'sequel' DB = Sequel.sqlite selection =
DataSetUnfilted方法删除所有过滤器,例如,它删除b=2。虽然在上述简单的情况下很容易重新添加,但在我的实际情况下,这会导致代码重复。您可以将选择规则存储在哈希中,然后重新使用哈希:
require 'sequel'
DB = Sequel.sqlite
selection = { a: 1, b: 2 }
ds1 = DB[:x].where( selection )
selection[:a] = 5 #change data
ds2a = ds1.unfiltered.filter(selection) # change selection
ds2b = DB[:x].where( selection ) #Alternative usage
puts ds1.sql #SELECT * FROM `x` WHERE ((`a` = 1) AND (`b` = 2))
puts ds2a.sql #SELECT * FROM `x` WHERE ((`a` = 5) AND (`b` = 2))
puts ds2b.sql #SELECT * FROM `x` WHERE ((`a` = 5) AND (`b` = 2))
我发现可以使用新方法filter\u exchange和filter\u exchange!修改数据集
过滤交换!修改原始数据集命令!即使是ds.dup.filter\u交换!将更改您原来的选择
使用filter_exchange,您将获得一个修改的数据集。到目前为止还没有经过很好的测试。我想这不是他们的主要用例,您可能希望进行基准测试,但您可以使用 请注意,绑定变量仅在与call和prepare一起使用时才能识别,因此不能仅使用,例如ds2.first
require 'sequel'
DB = Sequel.sqlite
module Sequel
class Dataset
def filter_exchange!( filter )
filter.each{|key, value|
opts[:where].args.each{|arg|
if arg.args.first == key
arg.args.pop
arg.args << value
end
}
}
self
end
def filter_exchange( filter )
sel = self.unfiltered
filter.each{|key, value|
opts[:where].args.each{|arg|
if arg.args.first == key
sel = sel.filter(key => value)
else
sel = sel.filter(arg)
end
}
}
sel
end
end
end
ds1 = DB[:x].filter(a:1, b:2)
puts ds1.sql #SELECT * FROM `x` WHERE ((`a` = 1) AND (`b` = 2))
puts ds1.filter_exchange( a: 7).sql #SELECT * FROM `x` WHERE ((`a` = 7) AND (`b` = 2)
puts ds1.sql #SELECT * FROM `x` WHERE ((`a` = 1) AND (`b` = 2)
puts ds1.filter_exchange!( a: 7).sql#SELECT * FROM `x` WHERE ((`a` = 7) AND (`b` = 2)
puts ds1.sql #SELECT * FROM `x` WHERE ((`a` = 7) AND (`b` = 2)
# initial args
ds1 = DB[:x].filter(a: :$a, b: :$b).bind(a: 1, b: 2)
ds1.call(:first) # or :select, :update, et al.
# then later
ds2 = ds1.bind(a: 42)
ds2.call(:first) # uses a = 42 and b = 2
# or pass the args directly into call()
ds2.call(:first, a: 42)