【问题标题】:Rails Active Record: has_many using custom id'sRails Active Record:has_many 使用自定义 id
【发布时间】:2020-11-18 03:29:42
【问题描述】:

我正在创建推荐系统。我的目标是通过唯一 id 而不是 Rails 的自定义 id 来引用对象。

这些是我的以下模型:

class User < ApplicationRecord
  set_primary_key :user_id
  has_many :referral, class_name: 'Referral', foreign_key: :user_referral
  has_many :referred, class_name: 'Referral', foreign_key: :user_referred
end

class Referral < ApplicationRecord
  belongs_to :user_referral, class_name: 'User'
  belongs_to :user_referred, class_name: 'User'
end

这些是我的 ActiveRecord 表:

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :first_name, null: false
      t.string :last_name, null: false
      t.string :email, null: false
      t.string :user_id, null: false
      t.timestamps
    end
  end
end

class CreateReferrals < ActiveRecord::Migration[6.0]
  def change
    create_table :referrals do |t|
      t.references :user_referral, foreign_key: { to_table: 'users' }, null: false
      t.references :user_referred, foreign_key: { to_table: 'users' }, null: false
      t.string :user_email, null: false
      t.timestamps
    end
  end
end

例如,我希望能够进行如下调用:

    User.create!(
      first_name: 'A',
      last_name: 'B',
      email: '123@test.com',
      user_id: 'userA'
    )
    User.create!(
      first_name: 'C',
      last_name: 'D',
      email: '456@test.com',
      user_id: 'userB'
    )
    Referral.create!(
      user_email: 'user1@test.com',
      user_referral: 'userA',
      user_referred: 'userB'
    )

但是,不接受“user_referral”和“user_referred”ID。有任何解决这个问题的方法吗?非常感谢

【问题讨论】:

  • Rails 在创建表时会自动添加一个唯一的 ":id" 列,我强烈推荐你使用它。 user_id 列应该在 Referral 表上,如果您在模型中适当地设置了关系,它将在查询时自动查看 user_id。当您尝试从关系中使用 Rails 辅助方法时,您正在打破 Rails 约定,因为看起来没有任何收获,但可能会令人头疼。用户有_many 推荐,推荐属于_to 用户,使用标准ID,你就完成了。
  • 你为什么要这样做?正如您已经注意到的那样,不使用表的主键违反了 Rails 的约定并且更难实现。值得麻烦吗?你想归档什么?
  • 我认为对于 foreign_key 选项,您必须通过 user_referrel_id - 外键引用字段而不是关联
  • what max 说 + user_referral: 'userA' 它应该是 user_referral_id:userA 应该是一个对象,而不是一个字符串。 t.references :user_referral 我认为应该创建一个 user_referal_id

标签: ruby-on-rails ruby api activerecord rspec


【解决方案1】:

让我们从声明一个具有非标准主键的表开始:

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users, id: :string, primary_key: :user_id do |t|
      t.string :first_name, null: false
      t.string :last_name, null: false
      t.string :email, null: false
      t.timestamps
    end
  end
end

然后,您需要为外键列使用正确的类型,并确保它们指向用户的正确列,因为默认值为 id

class CreateReferrals < ActiveRecord::Migration[6.0]
  def change
    create_table :referrals do |t|
      t.references :user_referral, 
        foreign_key: { to_table: 'users', primary_key: :user_id }, 
        null: false, 
        type: :string
      t.references :user_referred, 
        foreign_key: { to_table: 'users', primary_key: :user_id }, 
        null: false, 
        type: :string
      t.string :user_email, null: false
      t.timestamps
    end
  end
end

恭喜!你只是把最琐碎的问题弄得一团糟。

【讨论】:

  • 感谢帮助,对 Rails 来说还很陌生。虽然我收到“您无法重新定义主键列'broker_id'的错误。要定义自定义主键,请将 { id: false } 传递给 create_table”
  • 我真的建议你停止你正在做的任何事情,而是学习 Rails 约定 - 你让自己变得不必要的困难。
猜你喜欢
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
相关资源
最近更新 更多