ruby-on-rails - 自引用关联的 Rails 数据库约束

标签 ruby-on-rails ruby database

我正在构建一个涉及定向友谊关系的 Rails 网站。我知道在模型级别,它是一个 self 引用关联。还有像 has_and_belongs_to 这样的方法用于该关联。

我的问题是:如何为这种关系设置数据库级别的约束。我猜迁移会是这样的,它使用外键来保证参照完整性:

class CreateFriendships < ActiveRecord::Migration
  def change
    create_table :friendships do |t|
      t.belongs_to :user, null: false, foreign_key: true
      t.belongs_to :user, null: false, foreign_key: true

      t.integer :accepted, null: false, default: 0
    end
  end

但是当我运行 rake db:migrate 时,出现错误:

PG::DuplicateObject: ERROR:  constraint "fk_friendships_user_id" for relation "friendships" already exists

事实上,我什至不确定我是否有必要在这种情况下设置数据库约束,因为我看到有些人实现的友谊关系没有这样的数据库约束:

create_table :friendships do |t|
  t.integer :user_id
  t.integer :friend_id
  t.timestamps
end

根据 Rails 指南

The Active Record way claims that intelligence belongs in your models, not in the database. As such, features such as triggers or constraints, which push some of that intelligence back into the database, are not heavily used.

我不确定在这种情况下是否大量使用了数据库约束。

那么在这种情况下我真的有必要设置数据库级别的约束(使用外键)吗?或者我只需要实现模型级别的约束?谢谢!!

最佳答案

你已经声明了两次user关系:

  t.belongs_to :user, null: false, foreign_key: true
  t.belongs_to :user, null: false, foreign_key: true

看起来应该是这样的:

  t.belongs_to :user, null: false, foreign_key: true
  t.belongs_to :friend, null: false, foreign_key: true

回答您的问题:如何为这种关系设置数据库级别的约束? 答:就像你已经拥有的一样。

开发人员通常采用 rails 方式 并在模型中设置这些约束,但在数据库中设置它们是完全合理的。

编辑: 这将允许您使用 friend_id

创建一个表
class CreateFriendships < ActiveRecord::Migration
  def change
    create_table :friendships do |t|
      t.belongs_to :user, null: false, foreign_key: true
      t.integer :friend_id, null: false

      t.integer :accepted, null: false, default: 0
    end

    add_foreign_key :friendships, :users, column: :friend_id
  end
end

关于ruby-on-rails - 自引用关联的 Rails 数据库约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33097229/

相关文章:

node.js - 使用 NodeJS 访问 Firebird 数据库时出现未知表错误

ruby-on-rails - AbstractController::ActionNotFound - 奇怪的错误

ruby-on-rails - Devise - 通过curl点击/注册路线时收到401

ruby - 如何在 Ruby 中使用全局变量

ruby - 调用方法时.map和.times的区别

c# - 使用 C# 从数据库中保存和检索 rtf 文本

javascript - 将数据从html表单发送到mongodb数据库

ruby-on-rails - 我的 Rails 应用程序不会在生产模式下更新本地化字符串

ruby-on-rails - `autodetect' : No known ORM was detected

ruby-on-rails - 如何发送带有图像背景的电子邮件而不将此图像附加为下载文件?