Грязный статус Ruby Sequel в столбце json не работает с использованием Postgresql

Используя продолжение 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 никогда не удерживает столбец, я знаю, что могу указать столбец как «грязный», однако это означает, что мне нужно изменить все места, где этот столбец изменяется, а иногда это не так просто.

Пример того, как это не работает:

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

person zetacu    schedule 16.03.2017    source источник
comment
Значение :properties['foo'] изменилось после того, как вы его переопределили?   -  person Alex Holubenko    schedule 17.03.2017
comment
да, позвольте мне добавить этот звонок   -  person zetacu    schedule 17.03.2017


Ответы (1)


Это ожидаемое поведение Sequel по умолчанию. Если вы хотите обнаружить мутацию значений столбцов, вам необходимо использовать плагин модификации_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
person Jeremy Evans    schedule 17.03.2017
comment
tnx, который сработал, кстати, потрясающий драгоценный камень, я использую его уже несколько дней. - person zetacu; 17.03.2017