【问题标题】:Is foreign_key option has to be put as the options of belongs_to and has_many at the same time?foreign_key 选项是否必须同时作为belongs_to 和has_many 的选项?
【发布时间】:2023-03-21 05:43:01
【问题描述】:

我正在编写一些 Ruby-on-Rails 代码,我对在 belongs_to/has_many 关系中使用 foreign_key 有一些疑问。 我有两种型号,一种是Slogan,另一种是User。两者的关系是一个slogan对应一个用户(belongs_to),一个用户可以有很多slogan记录(has_many)。下面列出了两个模型的代码

# slogan.rb
class Slogan < ApplicationRecord
  belongs_to :author, class_name: :User, foreign_key: :author_id
end
# user.rb
class User < ApplicationRecord
  has_many :slogans
end

为了方便维护和语义,我把slogan上的关联名改成author(本来应该是user),把foreign_key改成author_id

我的问题是,如果我还想要他/她从用户记录中获得的所有口号,我是否还应该在用户模型中添加 foreign_key 选项?

谢谢!!

【问题讨论】:

    标签: ruby-on-rails associations


    【解决方案1】:

    我认为您不需要添加任何内容。但是您可以在 Rails 中使用双向关联。 Active Record 提供了:inverse_of 选项,因此您可以显式声明双向关联:

    class Author < ApplicationRecord
      has_many :books, inverse_of: 'writer'
    end
    
    class Book < ApplicationRecord
      belongs_to :writer, class_name: 'Author', foreign_key: 'author_id'
    end
    

    通过使用这个,你可以使用如下:

    a = Author.first
    b = a.books.first
    a.first_name == b.writer.first_name # => true
    a.first_name = 'David'
    a.first_name == b.writer.first_name # => true
    

    更多信息请参考:https://guides.rubyonrails.org/association_basics.html

    【讨论】:

    • 感谢您的回答。但我想知道在我的代码下,是否应该在两个关联中添加foreign_key?
    • 但是当我只在 Slogan 添加foreign_key 选项时。我可以找到一个标语记录的作者,但我找不到一个用户的所有标语记录。下面列出了错误消息error message picture
    【解决方案2】:

    在您的错误消息中,我看到 id 是 user_id 而不是 author_id。您可以将表中的 id 更改为 author_id 或从标语模型中删除 foreign_key。 foreign_key 约束告诉您的Slogan 模型应该在数据库中寻找author_id 列。它找不到该列,因为它被称为 user_id

    【讨论】:

    • 但我已经在我的 Slogan 表中添加了 author_id,我不知道这有什么问题。
    • 在您发布的错误中,它显示了 user_id。您的数据库方案文件是什么样的?另外,你的标语控制器是什么样子的?
    【解决方案3】:

    必须在User 模型中添加 foreign_key 选项。

    来自文档https://guides.rubyonrails.org/association_basics.html#has-many-association-reference

    按照惯例,Rails 假定用于保存外来的列 另一个模型上的键是该模型的名称,后缀为 _id 已添加。

    因此,如果您不添加 foreign_key 选项,Rails 会假定您在 slogans 表中有一个 user_id 列,这就是您有 this error 的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-21
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多