Ruby 删除数据集筛选器的一部分

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 =

如果应用了多个筛选器,如何创建一个新的数据集来删除或覆盖其中一个现有筛选器

ds1=DB[:x]。过滤器A:1,b:2 => ds2=ds1.filtera:42我想更改一个,而不是添加另一个 =>
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)