gpt4 book ai didi

ruby-on-rails - 如何使用不同的列作为外键强制 has_many 关联

转载 作者:行者123 更新时间:2023-12-03 15:59:47 25 4
gpt4 key购买 nike

陷入了 - 乍一看 - RoR 中的一个简单问题。我相信这很容易,但是这里没有一个答案对我帮助太大。

我有两个 ActiveRecord 模型:Foo有很多Bars :

class Foo < ApplicationRecord
has_many :bars
end

class Bar < ApplicationRecord
belongs_to :foo
end

这就像一个魅力。但我想使用 Foo 的另一个字段作为外键。默认为 foo_id我想使用 custom_id作为我的外键。所以我尝试了这个(正如网上建议的许多解决方案):
class Foo < ApplicationRecord
has_many :bars, :foreign_key => 'custom_id', :class_name => 'Bars'
end

class Bars < ApplicationRecord
belongs_to :foo, :class_name => 'Foo'
end

但这不起作用。即 ActiveRecord 保持绑定(bind) FooBars使用 foo_id .

注意:在 Foo 中包含 self.primary_key='custom_id' 会部分起作用。但我认为这不是一个好主意。我想保留 foo_id 作为主键

更新:

鉴于反馈-谢谢大家-,我在此处上传了该示例 https://github.com/montenegrodr/temporary_repository_ror :
  • Bar model
  • Foo model
  • ** This test is expected to PASS but it FAILS. **

  • 更新#2:

    答案不满足上述问题。为什么测试失败,我的假设是它不应该失败。

    更新#3:

    我仍然需要评估几个新的答案。将在 24 小时内完成。谢谢。

    更新 #4:

    谢谢你们所有的答案。但没有一个符合标准。我需要通过该测试。如果不可能,有人可以解释为什么吗?它是一个rails约束吗?

    最佳答案

    您需要指定不同的主键 为关系 如果你想实现你想要做的事情。

    澄清一下,这与更改 primary_key 不同。的模型。这种方式只是改变关系使用的主键。请参阅本文底部的示例。

    我使用 custom_id 更改了两者的键并将其中一项更改为 foo_id .这样您就可以更好地了解模型之间发生的情况。您可以同时使用 custom_id如果您愿意,但我建议保持 foo_id 的 rails 规范对于belongs_to 关联。

    如果您想同时使用这两个 custom_id,您必须添加一些特定的 foreign_keys
    以下是模型:


    class Foo < ApplicationRecord
    has_many :bars,
    primary_key: :custom_id,
    foreign_key: :foo_id
    end

    酒吧
    class Bar < ApplicationRecord
    belongs_to :foo,
    primary_key: :custom_id
    end

    迁移

    CreateFoos
    class CreateFoos < ActiveRecord::Migration[5.2]
    def change
    create_table :foos do |t|

    t.integer :custom_id, index: {unique: true}
    t.timestamps
    end
    end
    end

    创建酒吧
    class CreateBars < ActiveRecord::Migration[5.2]
    def change
    create_table :bars do |t|

    t.integer :foo_id, index: true
    t.timestamps
    end
    end
    end

    这是现在应该通过的更新的测试:

    测试
    require 'test_helper'

    class BarTest < ActiveSupport::TestCase
    test "the truth" do
    foo = Foo.new(id: 1, custom_id: 100)
    bar = Bar.new(foo: foo)

    assert bar.foo_id == foo.custom_id
    # bar.foo_id = 100
    # foo.custom_id = 100
    end
    end

    示例
    Foo.find(1) #<Foo id: 1, custom_id: 100>
    Bar.first #<Bar id: 1, foo_id: 100>

    Bar.first.foo = #<Foo id: 1, custom_id: 100>
    Bar.first.foo == Foo.find(1) # true

    可以看到,这个方法不会改变 Foo的主键本身。它改变了主键 Foo之间的关系和 Bar用途。 Bar 通过 custom_id: 100 分配给 foo , 但 foo 仍然可以找到它的 id: 1键,而不是它的 custom_id key 。

    关于ruby-on-rails - 如何使用不同的列作为外键强制 has_many 关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52994505/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com