2011-05-30 72 views
2

編輯:Rails的唯一訂單字段創建和更新操作

是否有可能創建將上增加獨特的自動遞增字段創建和使用Rails(類似於一個ID字段,但增加在SQL更新並在更新後重新分配)?例如:

創建記錄A(值:1)
創建記錄B(值:2)
更新記錄A(值:3)
更新記錄B(值:4)

我想設置拉同步,並需要一種方法來抓取自上次同步以來已創建或更新的所有記錄。

我最初使用'created_at'和'updated_at'字段,但發現它們很難處理,部分同步有些不準確。

編輯:

我使用PostgreSQL和SQLite作爲我的數據庫,所以希望有一個解決方案,將兩個系統的工作。

編輯:

爲了澄清,我想一個整數關口,從客戶端(最大的「同步」整數)我的服務器,並取回創建或更新所有記錄中記錄的創建後或更新。

回答

1

端向上添加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

你可以使用一個before_save回調,像這樣:

class MyModel < ActiveRecord::Base 
    before_save :increment 

    ... 

    protected 

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

你可以把通過定義和使用Callback Class這更可重複使用。

它使用自動版本控制的Gem /插件的另一種選擇(因此保留了version字段)。

+0

我需要該版本在所有記錄中都是唯一的(這不會那麼做)。 – 2011-05-30 00:46:35

+0

@KevinSylvestre啊,這稍微複雜一點:)我唯一能想到的是使用SQL MAX()函數。 – Jits 2011-05-30 00:52:43

+0

我不想在每次創建或更新時查詢所有表記錄。我想我正在尋找的是一個自動增量索引,它會在更新時增加。 – 2011-05-30 00:57:04

0

哎呀,沒有仔細閱讀。

如果要抓取自上次同步以來已修改的記錄,可以創建布爾字段以確定當前記錄是否已同步。默認情況下將其設置爲false,並在任何編輯時將其設置爲false。這應該讓你只拉取你需要的物品。

默認情況下會提供一個id屬性,它會自動遞增。默認情況下它是一個整數,但是如果你正在尋找一個guid,那麼讓我知道,我可以指出你一些好的資源。

至於從上次同步開始拉動記錄,您可以在運行同步時抓住最後一個ID並在再次同步時將其用作起始值。

+0

@Devin'id'屬性只在創建時不增加。 – 2011-05-30 00:45:27

+0

更新了我的帖子,沒有仔細閱讀。抱歉! – 2011-05-30 00:48:35

+0

@Devin不幸的是,這也不起作用。多個客戶端連接到數據源,我無法將其標記爲同步。 – 2011-05-30 00:50:43

0

所以......序列號與表格沒有關聯,對吧?

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 

這似乎是處理創建,新建/保存和更新的情況。但不要摧毀。

+1

我真的不明白這應該如何工作。我爲什麼要使用關聯? – 2011-05-30 01:01:35

+0

我更瞭解你的問題。看來你正在尋找一種服務,它會在每個新建/創建/更新操作中分配獨特的單調增加的序列號。我只是將其從Rails緩存中提取出來,並初始化啓動初始化的緩存項目部分。對不起,以前的帖子混亂。 – 2011-05-30 06:33:56

+0

我不認爲我可以那樣做。如果我的應用程序跨多個Web服務器運行,這將導致大量的不一致性,不是嗎? – 2011-05-30 06:36:20

-2

嘗試使用act_as_versioned gem。 它爲可用於同步的每條記錄設置一個版本字段。我認爲這將是跨客戶端進行同步的更好方式,因爲您可以比較服務器和客戶端上的版本並同步服務器上更高的版本。

該文檔是here。 而rubygem頁面是here

+0

我的答案有什麼問題。他要求提供版本記錄的方法,但我不明白這是如何超出範圍的,並且有人會解釋downvotes會有所幫助。 – 2011-05-30 01:49:35