删除依赖记录时不存在外键

时间:2015-10-10 09:00:50

标签: ruby-on-rails reference migration

我有两个型号。第一个:

class Keyword < ActiveRecord::Base

  has_many :words, dependent: :delete_all

end

第二个:

class Word < ActiveRecord::Base

end

我的迁移:

class Keywords < ActiveRecord::Migration
  def change
    create_table :keywords do |t|
      t.string :name, null: false, unique: true
      t.string :description, null: false 
      t.string :keys, null: false
      t.timestamps null: false
    end
  end
end

以及:

class Words < ActiveRecord::Migration
  def change
    create_table :words do |t|
      t.belongs_to :keyword
      t.string :name, null: false
      t.timestamps null: false
    end
  end
end

当我试图删除关键字实例时,Rails会抛出以下异常:

PG::UndefinedColumn: ERROR: column words.keyword_id does not exist LINE 1: DELETE FROM "words" WHERE "words"."keyword_id" = $1 ^ : DELETE FROM "words" WHERE "words"."keyword_id" = $1

所以我的问题是,为什么Rails创建keyword_id引用表而不是keywords_id?以及如何解决它。

3 个答案:

答案 0 :(得分:0)

首先,您需要为belongs_to模型添加Word关系:

class Word < ActiveRecord::Base
  belongs_to :keyword
end

其次,要为外键创建列keyword_id,您需要在迁移中使用add_reference方法:

class Words < ActiveRecord::Migration
  def change
    create_table :words do |t|
      t.string :name, null: false
      t.timestamps null: false
    end

    add_reference :words, :keyword, index: true, foreign_key: true
  end
end

如果您真正想要的是拥有多对多关系,则需要添加联接表,即KeywordsWords

答案 1 :(得分:0)

存储库中的代码实际上与您发布的迁移代码不同。在你的回购中你有:

t.belongs_to :keywords

将其更改为:

t.belongs_to :keyword

当您在问题中发布,然后重新创建数据库。

答案 2 :(得分:0)

您需要以下内容:

#app/models/keyword.rb
class Keyword < ActiveRecord::Base
   has_many :words
end

#app/models/word.rb
class Word < ActiveRecord::Base
   belongs_to :keyword
end

这将导致Rails在keyword_id表中查找words外键:

#words
id | keyword_id | name | created_at | updated_at

您似乎需要更改words表以包含keyword_id外键:

$ rails g migration ChangeWordsAddKeywordID

#db/migrate/change_words_add_keyword_id______.rb
class ChangeWordsAddKeywordID
   def change
     rename_column :words, :keywords_ids, :keyword_id
     ## OR ##
     create_column :words, :keyword_id, :integer
   end
end

$ rake db:migrate