好的..所以当谈到使用日期作为变化的指标时,我的老板有点疯狂。他不相信。
我想要做的是以与活动记录原生的日期更新相同的方式工作,而是基于不断增加的数字..我知道......自 1973 年以来的秒数不断变大好吧除非你算上夏令时之类的。
我想知道是否有任何想法,如何优雅地做到这一点。注意我有 20 张桌子需要这个,我是 DRY 的忠实粉丝。
好的..所以当谈到使用日期作为变化的指标时,我的老板有点疯狂。他不相信。
我想要做的是以与活动记录原生的日期更新相同的方式工作,而是基于不断增加的数字..我知道......自 1973 年以来的秒数不断变大好吧除非你算上夏令时之类的。
我想知道是否有任何想法,如何优雅地做到这一点。注意我有 20 张桌子需要这个,我是 DRY 的忠实粉丝。
看看http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html,我认为这正是你想要的。
ActiveRecord 中的乐观锁定意味着如果特定表上存在 lock_version 列,那么每次更改该记录时(当然是通过 ActiveRecord)它都会更新(+1)。
我最终在数据库中使用了一个大规模触发器。该函数在名为 data_changed 的新表中创建一条记录(或更新它)。
def create_trigger_function(schema)
puts "DAVE: creating trigger function for tenant|schema #{schema.to_s}"
sql = "CREATE OR REPLACE FUNCTION \""+schema+"\".insert_into_delta_table() RETURNS TRIGGER AS 'BEGIN
UPDATE \""+schema+"\".data_changes SET status = 1, created_at = now() where table_name = TG_TABLE_NAME and record_id = NEW.id;
INSERT INTO \""+schema+"\".data_changes (status, table_name, market_id, record_id, created_at)
( select m.* from \""+schema+"\".data_changes as ds right outer join
(select 1, CAST (TG_TABLE_NAME AS text ) as name , markets.id, NEW.id as record_id, now() from \""+schema+"\".markets) as m
on
ds.record_id = m.record_id
and ds.market_id = m.id
and table_name = name
where ds.id is null );
RETURN NULL;
END;' LANGUAGE plpgsql;"
connection.execute(sql);
end
现在我要做的就是找到所有改变的“产品”
update data_changes set status = 2 where status = 1 and table_name = 'products'
select * from products where id in (select record_id from data_changes where status = 2 and table_name = 'products')
update data_changes set status = 3 where status = 2 and table_name = 'products'
如果产品在我第一次更新后更新,但在我选择之前,它不会出现在我的选择中,因为它的 id 将重置为 1。
如果产品在我选择后更新,但是在我进行最后一次更新之前,它不会受到上次更新的影响。
我选择的内容将过时,但没有真正的方法可以避免这种情况。