Ruby Sequel json 列上的脏状态无法使用 Postgresql
Ruby Sequel dirty status on json column not working using Postgresql
使用 sequel 4.29.0。
我打算使用 before_save
sequel 钩子来触发一个动作,在这种情况下,我需要确定特定的列是否发生了变化,在以前的实现中我使用了 @changed_columns
sequel 实例变量以获取更改的列的列表以及类似的内容:
class MyModel < Sequel::Model
def before_save
special_method if @changed_columns.include? :properties
super
end
def special_method
...
end
end
这次我使用的是 Postgresql jsonb 类型的列(顺便说一句,非常方便)。每次我使用修改该列时,@changed_columns
永远不会保留该列,我知道我可以将一列指定为 "dirty",但这意味着我必须更改此列已更改的所有位置,有时不会就这么简单。
这不起作用的示例:
irb(main):001:0> MyModel.columns
=> [:id, :foo, :properties] # :foo is a string, :properties is jsonb
irb(main):002:0> my_model = MyModel.last
=> #<MyModel @values={:id=>37, :foo=>"bar", :properties=>{"foo"=>true}}>
irb(main):003:0> my_model.properties['foo'] = false
=> false
irb(main):004:0> my_model
=> #<MyModel @values={:id=>37, :foo=>"bar", :properties=>{"foo"=>false}}>
irb(main):005:0> my_model.modified?
=> false # this should be true since properties changed a value inside the hash
irb(main):006:0> my_model.foo = 'foo'
=> "foo"
irb(main):007:0> my_model
=> #<MyModel @values={:id=>37, :foo=>"foo", :properties=>{"foo"=>false}}>
irb(main):008:0> my_model.modified?
=> true
irb(main):009:0> my_model.changed_columns
=> [:foo] # should include the :properties column
这是 Sequel 的预期默认行为。如果你想检测列值的突变,你需要使用 modification_detection 插件:
DB.extension :pg_json
DB.create_table!(:bs){primary_key :id; jsonb :properties}
class B < Sequel::Model; end
B.plugin :modification_detection
B.create(:properties=>{'a'=>1})
b = B.first
b.properties['a'] = 2
b.modified?
# => true
使用 sequel 4.29.0。
我打算使用 before_save
sequel 钩子来触发一个动作,在这种情况下,我需要确定特定的列是否发生了变化,在以前的实现中我使用了 @changed_columns
sequel 实例变量以获取更改的列的列表以及类似的内容:
class MyModel < Sequel::Model
def before_save
special_method if @changed_columns.include? :properties
super
end
def special_method
...
end
end
这次我使用的是 Postgresql jsonb 类型的列(顺便说一句,非常方便)。每次我使用修改该列时,@changed_columns
永远不会保留该列,我知道我可以将一列指定为 "dirty",但这意味着我必须更改此列已更改的所有位置,有时不会就这么简单。
这不起作用的示例:
irb(main):001:0> MyModel.columns
=> [:id, :foo, :properties] # :foo is a string, :properties is jsonb
irb(main):002:0> my_model = MyModel.last
=> #<MyModel @values={:id=>37, :foo=>"bar", :properties=>{"foo"=>true}}>
irb(main):003:0> my_model.properties['foo'] = false
=> false
irb(main):004:0> my_model
=> #<MyModel @values={:id=>37, :foo=>"bar", :properties=>{"foo"=>false}}>
irb(main):005:0> my_model.modified?
=> false # this should be true since properties changed a value inside the hash
irb(main):006:0> my_model.foo = 'foo'
=> "foo"
irb(main):007:0> my_model
=> #<MyModel @values={:id=>37, :foo=>"foo", :properties=>{"foo"=>false}}>
irb(main):008:0> my_model.modified?
=> true
irb(main):009:0> my_model.changed_columns
=> [:foo] # should include the :properties column
这是 Sequel 的预期默认行为。如果你想检测列值的突变,你需要使用 modification_detection 插件:
DB.extension :pg_json
DB.create_table!(:bs){primary_key :id; jsonb :properties}
class B < Sequel::Model; end
B.plugin :modification_detection
B.create(:properties=>{'a'=>1})
b = B.first
b.properties['a'] = 2
b.modified?
# => true