Question

I'm looking at the foreigner gem and trying to create some foreign keys. However, the gems documentation says that you should create your foreign keys like this `add_foreign_key(from_table, to_table, options) but when I do that, it seems like it works backwards. For example, I have 3 models, Entry, Ingredient, and an association called EntryIngredient. Entry has many Ingredients through EntryIngredient, Ingredient has many Entries through EntryIngredients, and EntryIngredient belongs to both of these. Yet this is the code that works:

class EntryIngredient < ActiveRecord::Base
  belongs_to :entry
  belongs_to :ingredient  
end

class CreateEntryIngredients < ActiveRecord::Migration
  def self.up
    create_table :entry_ingredients do |t|
      t.references :entry
      t.references :ingredient
      t.integer :quantity
      t.string :unit

      t.timestamps
    end
    add_index :entry_ingredients, [:entry_id, :ingredient_id]

    add_foreign_key :entry_ingredients, :entries, :dependent => :delete
    add_foreign_key :entry_ingredients, :ingredients, :dependent => :delete
  end

  def self.down
    drop_table :entry_ingredients
  end
end

By the docs I would think that the foreign key should actually be added like this:

add_foreign_key :entries, :entry_ingredients, :dependent => :delete
add_foreign_key :ingredients, :entry_ingredients, :dependent => :delete

But when I run the migration, that returns me a

Mysql2::Error: Key column 'entry_ingredient_id' doesn't exist in table: ALTER TABLE `entries` ADD CONSTRAINT `entries_entry_ingredient_id_fk` FOREIGN KEY (`entry_ingredient_id`) REFERENCES `entry_ingredient`(id) ON DELETE CASCADE

Can someone explain to me whats happening here? Why am I dyslexic?

Was it helpful?

Solution

I've verified this, if someone thinks I'm still not getting it please explain to me. But, unless my English is bad, I believe that the gem is documented incorrectly. The correct syntax is actually:

add_foreign_key(to_table, from_table, options)

So with that I would do add_foreign_key :entry_ingredients, :entries, :dependent => :delete This logic says to me, add a foreign key to the table entry_ingredients, from table entries as entry_id, with options...

While by the documentations logic I would use this code add_foreign_key :entries, :entry_ingredients, :dependent => :delete which says to me, add a foreign key from entries (as entry_id), to entry_ingredients, with options... However, what in fact happens is we are adding a foreign key to entries, from entry_ingredients (as entry_ingredients_id). This is wrong, and not the intended result. Here is the error I receive when following the documentations method to prove it:

Mysql2::Error: Key column 'entry_ingredient_id' doesn't exist in table: ALTER TABLE `entries` ADD CONSTRAINT `entries_entry_ingredient_id_fk` FOREIGN KEY (`entry_ingredient_id`) REFERENCES `entry_ingredients`(id) ON DELETE CASCADE

I've reported this as an issue on github so hopefully he fixes the documentation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top