0

I have two models linked with each other by two has_many / belongs_to association with a foreign key, but I have some trouble to save any fight object.

Here my models:

Fight.rb

belongs_to :winner, class_name: 'Fighter', foreign_key: :winner_id, inverse_of: 'winned_fights'
belongs_to :looser, class_name: 'Fighter', foreign_key: :looser_id, inverse_of: 'loosed_fights'

Fighter.rb

has_many :winned_fights, class_name: 'Fight', foreign_key: :winner_id, inverse_of: 'winner'
has_many :loosed_fights, class_name: 'Fight', foreign_key: :looser_id, inverse_of: 'looser'

db/schema.rb

create_table "fights", force: :cascade do |t|
  ...
  t.integer "winner_id"
  t.integer "looser_id"
  t.index ["looser_id"], name: "index_fights_on_looser_id"
  t.index ["winner_id"], name: "index_fights_on_winner_id"
end

create_table "fighters", force: :cascade do |t|
  t.string "name"
  ...
end

This is what happens when I try to save a Fight object:

ActiveRecord::StatementInvalid (SQLite3::SQLException: no such table: main.loosers: INSERT INTO "fights" ("winner_punches", "looser_punches", "victory_type", "rounds", "winner_id", "looser_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?)):

Here is the SQL request that fails:

Fight Create (1.5ms)  INSERT INTO "fights" ("winner_punches", "looser_punches", "victory_type", "rounds", "winner_id", "looser_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?)  [["winner_punches", 1], ["looser_punches", 1], ["victory_type", 0], ["rounds", 1], ["winner_id", 18], ["looser_id", 2], ["created_at", "2018-10-15 15:46:13.479488"], ["updated_at", "2018-10-15 15:46:13.479488"]]

I can't figure out if the problem come from my has_many / belongs_to association declaration or if it is a DB problem.

What's currently working:

  • figther.winned_fights
  • figther.loosed_fights

Does someone would guide me to the right path ?

XavM
  • 863
  • 9
  • 22

2 Answers2

1

First thing, I don't think you need to put the foreign_key option in the fight model, as it's usually taken from the association name.

Now, the problem is actually in the database, when you wrote or generated the migration to build the model, you probably used a belongs_to field (or references field), which automatically creates a foreign key constraint on the database.

So you have a foreign key constraint from the column looser_id to a table (automatically guessed) loosers. You should check your schema.rb to see if this is correct, in which case, just remove that constraint or fix it using another migration : foreigner - remove foreign key

Uelb
  • 3,947
  • 2
  • 21
  • 32
  • 1
    Thanks, it was exactly the problem. I specified `t.references :looser, foreign_key: true, index: true` in my migration. I just had to switch from true to false – XavM Oct 15 '18 at 16:19
0

You should always try to stick to migrations to work with db modifications.

you can add the foreign keys to the respective tables after they have been created and it will properly index it in Rails 4+

rails g migration addWinnerReferencesToFights winner_id:references
rails g migration addLooserReferencesToFights looser_id:references

PS - it also helps a lot if you spell the models correctly ie: there is no english word called winned nor loosed >>> correct plurals are wins and losses (loose means something not tight or affixed)

Denis S Dujota
  • 543
  • 5
  • 13