【问题标题】:Insert sequence value in a column within the scope of a foreign key - Rails and Postgres在外键范围内的列中插入序列值 - Rails 和 Postgres
【发布时间】:2018-08-30 15:13:45
【问题描述】:

我想在我的表中有一个在外键范围内自动递增的列。

   id   |   foreign_key_column   |   this_column_i_want
--------------------------------------------------------
   1    |         1              |           1
   2    |         1              |           2   
   3    |         1              |           3
   4    |         2              |           1
   5    |         2              |           2
   6    |         3              |           1

这种模式是否可以通过 Rails 迁移实现?

考虑以下场景: 该表代表订单表。 如果此表存储来自多个商店的订单,则外键列将是 store_id。现在,不同的商店需要他们的发票在他们的范围内是连续的。早些时候,发票是全球连续的。

因此每个商店的发票编号必须从 1 开始,并根据为该特定商店创建的记录不断增加。

希望这有助于解释这个问题。

【问题讨论】:

  • 您可以创建DB triggers in Postgres 来做几乎任何事情。 Rails 迁移中没有对此的内置支持,但可以在迁移中使用原始 SQL。
  • 我认为这个gem 可以帮助你
  • @fongfan999 我认为您可以将其添加为答案。它完全解决了 OP 的问题。
  • @WayneConrad,非常感谢

标签: sql ruby-on-rails postgresql schema


【解决方案1】:

有一个名为sequenced 的宝石。我认为它会解决你的问题。

Sequenced 是一个简单的 gem,它为 ActiveRecord 模型。这个 gem 提供了一个acts_as_sequenced 宏 自动为每条记录分配一个唯一的、连续的 ID。这 顺序 ID 不是数据库主键的替代品,而是 而是添加另一种方法来检索对象而不暴露 主键。


gem 提供了一个 Ruby/Rails 实现。它使用ActiveModel::Callbacks设置sequential_id列的值:before_save :set_sequential_ids[link]

def acts_as_sequenced(options = {})
  # ...
  include Sequenced::ActsAsSequenced::InstanceMethods

  mattr_accessor :sequenced_options, instance_accessor: false

  self.sequenced_options = []

  before_save :set_sequential_ids
  # ...
end

这里是setter方法[link]

def set
  return if id_set? || skip?
  lock_table
  record.send(:"#{column}=", next_id)
end

【讨论】:

  • 能否告诉我这个 gem 是提供 DB 实现还是 Ruby 实现?答案最接近我需要达到的目标,但如果能获得更多信息,那就太好了。
  • 嗨@Rohit,我刚刚更新了我的答案。请看看:)
猜你喜欢
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多