【问题标题】:How can I use GREATEST and LEAST in a Rails migration?如何在 Rails 迁移中使用 GREATEST 和 LEAST?
【发布时间】:2017-10-12 23:19:09
【问题描述】:

我需要确保表 friendshipsrequester_idaccepter_id 列上的双向唯一性。

Table: friendships

requester_id | accepter_id
--------------------------
           1 |           2
           2 |           1  <-- this should not be possible

作为一个可以考虑的解决方案,我发现了这种方法:Postgresql enforce unique two-way combination of columns

create unique index ifriendz on friendz(greatest(from_id,to_id), least(from_id,to_id));

我正在尝试编写 Rails 迁移(我知道我也可以使用纯 SQL,但我希望它干净)。

这是我重写命令的尝试。它不起作用。

class AddBidirectionalUniqueConstraintToFriendships < ActiveRecord::Migration
  def change
    add index :friendships, greatest[:requester_id, :accepter_id], least[:requester_id, :accepter_id], unique: true
  end
end

【问题讨论】:

  • 我对 Rails ActiveRecord 一无所知,但如果它与大多数其他 ORM 框架一样,那么它可能仅限于大多数 ANSI 风格的 SQL 功能。 greatestleast 函数在很大程度上是特定于数据库的。 Postgres 和 MySQL 支持它,但不是所有的数据库。因此,您尝试做的事情可能是不可能的。

标签: sql ruby-on-rails


【解决方案1】:

您可以使用execute 命令运行任意 SQL 命令。

例如:

class AddBidirectionalUniqueConstraintToFriendships < ActiveRecord::Migration
  def up
    execute <<-SQL
      create unique index ifriendz on friendz(greatest(from_id,to_id), least(from_id,to_id));
    SQL
  end

  def down
    execute <<-SQL
      drop index ifriendz;
    SQL
  end
end

```

【讨论】:

  • 谢谢。考虑到这可能仅适用于 MySQL 和 PostgreSQL,这是否干净?
  • 这还不够。 db/schema.rb 不会包含正确的索引,除非您也切换到 db/structure.sql
  • mu 是正确的,在您的config/application.rb 中,您需要设置config.active_record.schema_format = :sql 以使用db/structure.sql
猜你喜欢
  • 2011-04-17
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
  • 1970-01-01
相关资源
最近更新 更多