在rails / postgres中引用表两次

时间:2016-10-24 04:33:21

标签: ruby-on-rails ruby postgresql rails-activerecord

我在Post中使用PostgreSQL作为我的数据库。我有一个用户模型和一个产品模型。我想创建一个交易模型,我想引用用户两次,一次作为买家,一次作为卖家。我根据这篇文章的建议生成了模型(由toasterlovin回答) Write a migration with reference to a model twice 但是当我使用PostgreSQL时它会给我一个错误(使用SQLite它工作正常)。我收到以下错误。我该怎么做才能解决这个问题?

  

{StandardError:发生错误,此以及所有后续迁移都已取消:

     

PG :: UndefinedTable:错误:关系"买家"不存在   :ALTER TABLE"交易"添加约束" fk_rails_0b24a7fcc3"
  外键(" buyer_id")
    参考"买家" (" ID&#34)
  C:/Users/Powerhouse/Desktop/CodingDojo/ruby/rails/demo/db/migrate/20161024032156_create_transactions.rb:3:in change'
C:in
migrate'
  ActiveRecord :: StatementInvalid:PG :: UndefinedTable:ERROR:relation"买家"不存在   :ALTER TABLE"交易"添加约束" fk_rails_0b24a7fcc3"
  外键(" buyer_id")
    参考"买家" (" ID&#34)
  C:/Users/Powerhouse/Desktop/CodingDojo/ruby/rails/demo/db/migrate/20161024032156_create_transactions.rb:3:in change'
C:in
migrate'
  PG :: UndefinedTable:错误:关系"买家"不存在   C:/Users/Powerhouse/Desktop/CodingDojo/ruby/rails/demo/db/migrate/20161024032156_create_transactions.rb:3:in change'
C:in
migrate'
  任务:TOP => DB:迁移
  (通过使用--trace运行任务查看完整跟踪)}

模特

class User < ActiveRecord::Base
    has_many :products
    has_many :sales,  :class_name => 'Transaction', :foreign_key => 'seller_id'
    has_many :purchases,  :class_name => 'Transaction', :foreign_key => 'buyer_id
end

产品型号

class Product < ActiveRecord::Base
  belongs_to :user
end

交易模式

class Transaction < ActiveRecord::Base
  belongs_to :buyer, :class_name => 'User'
  belongs_to :seller, :class_name => 'User'
  belongs_to :product
end

迁移文件

用户

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.timestamps null: false
    end
  end
end

产品

class CreateProducts < ActiveRecord::Migration
  def change
    create_table :products do |t|
      t.references :user, index: true, foreign_key: true
      t.string :name

      t.timestamps null: false
    end
  end
end

交易

class CreateTransactions < ActiveRecord::Migration
  def change
    create_table :transactions do |t|
      t.references :buyer, index: true, foreign_key: true
      t.references :seller, index: true, foreign_key: true
      t.references :product, index: true, foreign_key: true

      t.timestamps null: false
    end
  end
end

2 个答案:

答案 0 :(得分:1)

这是由于PostgreSql无法理解如何创建自定义关联外键。

尝试将迁移文件更改为

class CreateTransactions < ActiveRecord::Migration
  def change
    create_table :transactions do |t|
      t.integer :buyer_id
      t.integer :seller_id
      t.integer :product_id

      t.timestamps null: false
    end
    add_index(:transactions, :buyer_id)
    add_index(:transactions, :seller_id)
    add_index(:transactions, :product_id)
    add_foreign_key :transactions, :users, column: :buyer_id
    add_foreign_key :transactions, :users, column: :seller_id
  end
end

它会自动将buyer_id链接到user,并具有

的功能

belongs_to :buyer, :class_name => 'User'

上面一行将buyer_id作为外键。

您也可以尝试

class CreateTransactions < ActiveRecord::Migration
  def change
    create_table :transactions do |t|
      t.references :buyer, index: true
      t.references :seller, index: true
      t.references :product, index: true
      t.timestamps null: false
    end
    add_foreign_key :transactions, :users, column: :buyer_id
    add_foreign_key :transactions, :users, column: :seller_id
  end
end

答案 1 :(得分:0)

你的问题是当ActiveRecord看到这个时:

t.references :buyer, index: true, foreign_key: true

它尝试在数据库中创建一个外键(因为foreign_key: true),但是命名约定告诉AR它应该链接到buyers表(因为你引用了{{ 1}})。

就像在模型中指定:buyer一样:

class_name:

告诉AR不要使用传统的belongs_to :buyer, :class_name => 'User' 名称,您可以通过修改Buyer选项来覆盖迁移中的约定:

:foreign_key

明确命名表。同样,对于没有使用传统命名方案的其他参考文献:

t.references :buyer, index: true, foreign_key: { to_table: :users }