Rails和外键

时间:2011-12-03 03:33:17

标签: ruby-on-rails ruby postgresql foreign-keys

我在铁轨上遇到了愚蠢的魔法问题!

所以,我用外键创建了表(我使用的是sparkfly-foreigner gem)。

class CreateCourses < ActiveRecord::Migration
  def change
    create_table :courses do |t|
      t.string :coursename,
      t.integer :subject,
      t.integer :theme,
      t.integer :hours,
      t.decimal :price,
      t.foreign_key :subject, :column => :subject, :dependent => :delete
      t.foreign_key :theme, :column => :theme, :dependent => :delete
      t.timestamps
    end
  end
end

它在终端和我的rails webapp中工作正常。

然后我正在创建另一张桌子。

class CreateGroupps < ActiveRecord::Migration
  def change
    create_table :groupps do |t|
      t.string :groupname
      t.integer :courseid
      t.integer :number,
      t.foreign_key :course, :column => :courseid, :dependent => :delete
      t.timestamps
    end
  end
end

魔法开始了。我在Groupps的网络表单中写了不存在的courseid,它创建了数据库中的记录!当我使用终端时,我得到了这个

rails_dev=> select * from groupps
rails_dev-> ;
 id | groupname | courseid | number |         created_at         |         updated_at         
----+-----------+----------+--------+----------------------------+----------------------------
  1 | 12        |          |      1 | 2011-12-03 02:51:06.154261 | 2011-12-03 02:51:06.154261
(1 row)

rails_dev=> insert into groupps values (2,12,0,0);                                                                                                                                                          ERROR:  insert or update on table "groupps" violates foreign key constraint "groupps_courseid_fkey"
DETAIL:  Key (courseid)=(0) is not present in table "courses".

怎么可能?当我错了?我是铁杆和红宝石的新手。

1 个答案:

答案 0 :(得分:1)

此输出:

 id | groupname | courseid | number |         created_at         |         updated_at         
----+-----------+----------+--------+----------------------------+----------------------------
  1 | 12        |          |      1 | 2011-12-03 02:51:06.154261 | 2011-12-03 02:51:06.154261
(1 row)

表示你在courseid中有一个NULL,就你的表和外键而言,这很好。您可以在引用列中使用NULL,您可能希望将:null => false添加到courseid

create_table :groupps do |t|
  t.string :groupname
  t.integer :courseid, :null => false
  t.integer :number,
  t.foreign_key :course, :column => :courseid, :dependent => :delete
  t.timestamps
end

BTW,因为你已经在psql,你可以使用\d groupps来查看你的表的结构,约束(包括FK),甚至是哪些FK引用你的表。您可能也对\pset null

感兴趣
  

null
  设置要打印的字符串以代替空值。默认是不打印任何内容,很容易被误认为是空字符串。例如,有人可能更喜欢\pset null '(null)'