I am trying to make what should be a pretty straight forward association between two models. The models are games
and categories
.
I first setup the two models.
create_table "games", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.bigint "user_id"
t.string "title"
t.integer "min_play_time"
t.integer "min_players"
t.integer "max_players"
t.text "description"
t.string "image"
t.string "rules_url"
t.string "playthrough_url"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "max_play_time"
t.integer "min_age"
t.integer "best_number_of_players"
t.integer "recommended_min_age"
t.integer "bgg_number"
t.integer "year_published"
t.index ["user_id"], name: "index_games_on_user_id"
end
create_table "categories", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.bigint "bgg_id"
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Then I setup my join table using rails g migration CreateJoinTableCategoryGame Category Game
.
Migration file looks like this:
class CreateJoinTableCategoryGame < ActiveRecord::Migration[5.2]
def change
create_join_table :Categories, :Games do |t|
t.index [:category_id, :game_id]
t.index [:game_id, :category_id]
end
end
end
I migrated my database. Then I went into the console and created a test category and game and tried to associate them, this is what I got.
Game.find(1).categories << Category.find(1)
(0.4ms) SET @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
Game Load (0.4ms) SELECT `games`.* FROM `games` WHERE `games`.`id` = 1 LIMIT 1
Category Load (0.4ms) SELECT `categories`.* FROM `categories` WHERE `categories`.`id` = 1 LIMIT 1
(0.2ms) BEGIN
(0.3ms) ROLLBACK
Traceback (most recent call last):
1: from (irb):1
ActiveModel::UnknownAttributeError (unknown attribute 'game_id' for Game::HABTM_Categories.)```
Run rails db:rollback
to reverse previous migration of CreateJoinTableCategoryGame
and then change the code to this
create_join_table :categories, :games do |t|
t.index [:category_id, :game_id]
t.index [:game_id, :category_id]
end
now run rails db:migrate
and run Game.find(1).categories << Category.find(1)
in rails console.
This is happening because table names are in lowercase and you're passing camelcase.
Also your models should look like this:
class Game < ActiveRecord::Base
has_many :category_games
has_many :categories, through: :category_games
end
class Cateogry < ActiveRecord::Base
has_many :category_games
has_many :games, through: :category_games
end
class CategoryGame < ActiveRecord::Base
belongs_to :game
belongs_to :category
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.