Уникальное поле заказа Rails для операций создания и обновления - PullRequest
2 голосов
/ 30 мая 2011

Изменить:

Можно ли создать уникальное поле автоматического приращения, которое будет увеличиваться при создании и обновлении в SQL с использованием Rails (аналогично полю id, но увеличивается и переназначается после обновления)? Например:

Создать запись A (значение: 1)
Создать запись B (значение: 2)
Обновить запись A (значение: 3)
Обновить запись B (значение: 4)

Я пытаюсь настроить синхронизацию по запросу, и мне нужен способ получить все записи, которые были созданы или обновлены после предыдущей синхронизации.

Первоначально я использовал поля 'create_at' и 'updated_at', но обнаружил, что с ними трудно работать и что-то неточно для частичной синхронизации.

Edit:

Я использую Postgresql и Sqlite в качестве своих баз данных, так что, надеюсь, существует решение, которое будет работать для обеих систем.

Edit:

Чтобы уточнить, я хочу передать клиенту одно целое число (наибольшее целое число синхронизации) и получить обратно все записи, созданные или обновленные после создания или обновления этой записи.

Ответы [ 5 ]

1 голос
/ 03 июня 2011

Закончилось добавление целого поля sequence в мою модель и настройка следующей миграции:

class CreateSequence < ActiveRecord::Migration
  def self.up
    begin
      execute "CREATE SEQUENCE sequence"
    rescue
    end
  end

  def self.down
    begin
      execute "DROP SEQUENCE sequence"
    rescue
    end
  end
end

Затем в моей модели я добавил:

before_save do
  self.sequence = self.class.sequence
end

def self.sequence
  s ||= self.connection.select_value("SELECT nextval('sequence') ") rescue nil
  s ||= self.connection.select_value("SELECT strftime('%s','now')") rescue nil
  return 
end

Примечание : для Sqlite последовательности не поддерживаются, поэтому вместо этого требуется выбор формы 'эпохи' базы данных.Тем не менее, это имеет отрицательный побочный эффект, заключающийся в том, что последовательность не является уникальной для быстрого создания.Однако в моем случае это не было проблемой.

0 голосов
/ 30 мая 2011

Попробуйте использовать камень act_as_versioned. Он устанавливает поле версии для каждой записи, которую вы можете использовать для синхронизации. И я думаю, что это был бы лучший способ синхронизации между клиентами, так как вы можете сравнить версию на сервере и клиенте и синхронизировать те, которые выше на сервере.

Документы здесь . И страница rubygem здесь здесь .

0 голосов
/ 30 мая 2011

Упс, не читал слишком внимательно.

Если вы хотите получить записи, которые были изменены с момента последней синхронизации, вы можете создать логическое поле для определения, была ли синхронизирована текущая запись.Установите его в false по умолчанию и установите в false при любом редактировании.Это должно позволить вам извлекать только те элементы, которые вам нужны.

Существует атрибут id, который предоставляется по умолчанию и который автоматически увеличивается.По умолчанию это целое число, однако, если вы искали гид, дайте мне знать, и я могу указать вам на хорошие ресурсы.

Что касается извлечения записей со времени последней синхронизации, вы можете просто взять последнююидентификатор при запуске синхронизации и использовать его в качестве начального значения при повторной синхронизации.

0 голосов
/ 30 мая 2011

Итак ... серийный номер не столько связан со строкой, сколько с таблицей, верно?

class SerialNumber < AR::Base
  has_many :thingies
  # just has an integer serial number field
end

class Thingie < AR::Base
  belongs_to :serial_number  # probably want to include this in default scope

  before_create :bump_serial
  before_save : bump_serial

private
  def bump_serial
    self.serial_number ||= 0
    self.serial_number += 1
  end
end

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

0 голосов
/ 30 мая 2011

Вы можете использовать обратный вызов before_save, например, так:

class MyModel < ActiveRecord::Base
  before_save :increment

  ...

  protected

  def increment
    self.revision ||= 1
    self.revision += 1
  end
end

Вы можете сделать это более удобным для повторного использования, определив и используя Класс обратного вызова .

Другой вариант - использовать Gem / плагин, который выполняет автоматическое управление версиями (и, следовательно, поддерживает поле version).

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