活动记录中的外键自我指示has_many:through

时间:2014-12-16 10:33:30

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

我使用带有schema_plus gem的rails 4。

我希望能够以这种方式访问​​模型:

    phrase = Phrase.create(name:'car')
    another_phrase = Phrase.create(name:'vehicle')
    phrase.synonym_phrases << another_phrase
    p phrase.synonym_phrases

我的关系设置:

    class Phrase < ActiveRecord::Base
      has_many :synonyms
      has_many :synonym_phrases, through: :synonyms
    end

    class Synonym < ActiveRecord::Base
      belongs_to :phrase
      belongs_to :synonym_phrase, class_name: 'Phrase', foreign_key: :synonym_id
    end

在migratind数据库之后,生成的模式如下所示:

    ActiveRecord::Schema.define(version: 20141211103911) do

      create_table "phrases", force: true do |t|
        t.string   "name"
        t.datetime "created_at"
        t.datetime "updated_at"
      end

      create_table "synonyms", force: true do |t|
        t.integer  "phrase_id"
        t.integer  "synonym_id"
        t.datetime "created_at"
        t.datetime "updated_at"
        t.index ["phrase_id"], :name => "fk__synonyms_phrase_id"
        t.index ["synonym_id"], :name => "fk__synonyms_synonym_id"
        t.foreign_key ["phrase_id"], "phrases", ["id"], :on_update => :no_action, :on_delete => :no_action, :name => "fk_synonyms_phrase_id"
        t.foreign_key ["synonym_id"], "synonyms", ["id"], :on_update => :no_action, :on_delete => :no_action, :name => "fk_synonyms_synonym_id"
      end

其中第二个外键分配错误,因为它指向同义词表,而是指向短语表(self-referentiall)。

我发现,向迁移添加foreign_key: { references: :phrases }可以解决问题。

    # db/migrate/20141211103911_create_synonyms.rb
    class CreateSynonyms < ActiveRecord::Migration
      def change
        create_table :synonyms do |t|
          t.integer :phrase_id
          t.integer :synonym_id, foreign_key: { references: :phrases }

          t.timestamps
        end
      end
    end

数据库删除和迁移后,架构生成正确。

    # db/schema.rb
    -    t.foreign_key ["synonym_id"], "synonyms", ["id"], :on_update => :no_action, :on_delete => :no_action, :name => "fk_synonyms_synonym_id"
    +    t.foreign_key ["synonym_id"], "phrases", ["id"], :on_update => :no_action, :on_delete => :no_action, :name => "fk_synonyms_synonym_id"

我很好奇有没有办法在不编辑迁移文件的情况下设置这种关系?在模型中可能还有其他一些命名约定?有什么想法吗?

0 个答案:

没有答案