Rails update_all с hstore

Какой хороший способ обновить несколько записей в столбцах hstore с помощью activerecord? Прямо сейчас я перебираю, обновляю и сохраняю вот так:

time = Time.now.to_s
scoped_tasks.each do |task|
  task.data[:last_checked] = time
  task.save!
end

Есть ли способ сделать это с update_all запрос? Одно решение, которое я видел, выглядит так:

MyModel.update_all(:properties => ActiveRecord::Coders::Hstore.dump({'a' => 1}))

Но проблема в том, что он перезаписывает весь столбец, поэтому другие значения теряются. Я также видел это:

MyModel.update_all("data = data || hstore('a', 'blah')")

Но почему-то я возвращаюсь 0 для значения. Похоже, что это будет работать только в том случае, если магазин пуст.

2 ответа

Решение

Я сам боролся с тем же вопросом, вот как я смог его решить:

MyModel.update_all([%(data = data || hstore(?,?)), 'a', 'new_value']))

Основным исправлением для этого было обертывание действия update_all в [] и%(). Я все еще пытаюсь выяснить, как% () определяет SET в Postgre SQL, так что если у кого-нибудь есть объяснение, которое будет очень полезным.

В моем случае я тоже фактически удалял ключ (на самом деле я хотел обновить имя ключа, но сохранить значение). Так что, если у кого-то есть такая проблема, код выглядит так:

MyModel.update_all([%(data = delete("data",?)), 'a'])

Я надеялся выполнить оба действия в одном вызове, но это создавало действительно странную команду в SQL, где второе действие было добавлено как часть предложения WHERE, а не SET. Все еще немного черной магии для меня, но, надеюсь, это поможет...

Если вы используете

MyModel.update_all(:properties => ActiveRecord::Coders::Hstore.dump({'a' => 1}))

тогда он будет очищен от других значений, и если вы попытаетесь использовать

MyModel.update_all("data = data || hstore('a', 'blah')") это будет работать, только если в столбце hstore есть какое-либо значение, поэтому попробуйте использовать комбинацию обоих

if (hstore_column_name).present? MyModel.update_all("data = data || hstore('a', 'blah')") else MyModel.update_all(:properties => ActiveRecord::Coders::Hstore.dump({'a' => 1}))

Другие вопросы по тегам