ruby-on-rails 使用自定义主键时如何在Rails中设置引用

k75qkfdt  于 2023-02-06  发布在  Ruby
关注(0)|答案(1)|浏览(125)

我正在尝试将从Sellix API获取的数据保存到Rails应用程序的数据库中。
基本上有4种模式:产品、优惠券、订单和反馈。
Sellix在每个名为"uniqid"的对象上都有自己唯一的id,因此我决定也将其用作模型中的主键。
对于某些模型,我希望保存对其他表的引用。例如,我希望将优惠券作为订单的引用,以了解在下订单时使用了哪种优惠券。
这是两个模式现在的情况:

create_table "coupons", id: false, force: :cascade do |t|
    t.string "uniqid", null: false
    t.string "code"
    t.decimal "discount"
    t.integer "used"
    t.datetime "expire_at"
    t.integer "created_at"
    t.integer "updated_at"
    t.integer "max_uses"
    t.index ["uniqid"], name: "index_coupons_on_uniqid", unique: true
  end
create_table "orders", id: false, force: :cascade do |t|
    t.string "uniqid", null: false
    t.string "order_type"
    t.decimal "total"
    t.decimal "crypto_exchange_rate"
    t.string "customer_email"
    t.string "gateway"
    t.decimal "crypto_amount"
    t.decimal "crypto_received"
    t.string "country"
    t.decimal "discount"
    t.integer "created_at"
    t.integer "updated_at"
    t.string "coupon_uniqid"
    t.index ["uniqid"], name: "index_orders_on_uniqid", unique: true
  end

coupon_uniqid on orders表是对相关息票的引用。
Sellix API上的order对象已经有了那个引用,所以现在我可以这样保存它。
但是当我显示所有订单时,我必须使用Coupon.find_by(uniqid: order.coupon_uniqid),它总是迭代本地数据库中的每个优惠券记录,以找到如下所示的记录。
CACHE Coupon Load (0.0ms) SELECT "coupons".* FROM "coupons" WHERE "coupons"."uniqid" = $1 LIMIT $2 [["uniqid", "62e95dea17de385"], ["LIMIT", 1]]
如果我能保留优惠券引用而不是uniqid,我就可以摆脱这种情况。
这基本上就是我想弄清楚的。

jdgnovmf

jdgnovmf1#

    • YAGNI.**您应该考虑的一种更好的方法是,只使用自己的主键,并将uniqid作为次要标识符,以便在根据记录的外部id查找记录时使用。

这样,一切都可以在最小配置下工作。
如果您真的想打破惯例,可以在创建表时配置主键的类型和名称:

create_table :orders, id: :string, primary_key: :uniqid do |t|
  # ...
end
class Order < ApplicationRecord
  self.primary_key = :uniqid
end

由于此列不会自动生成主键,因此您还需要在所有测试中处理它。
然后,您必须在创建外键列时提供额外的配置,以便它们具有相同的类型并指向另一个表上的正确列:

class AddOrderIdToCoupons < ActiveRecord::Migration[7.0]
  def change
    add_reference :coupons, :order, 
      type: :string, # default is bigint
      null: false, 
      foreign_key: { primary_key: "uniqid" }
  end
end

您还需要为所有关联添加配置:

class Coupon < Application
  belongs_to :order, primary_key: "uniqid"
end

class Order < Application
  has_many :coupons, primary_key: "uniqid"
end

相关问题