HABTM Duplicate Entries

I have 2 Game and Theme models, and they have the has_and_belongs_to_many association. I tried many solutions to prevent duplicate entries in the games_themes table, but no solutions work. The problem is that games_themes is a table, but it is not a model, so I cannot figure out how to efficiently execute it.

Here is the solution I tried

 class Theme < ActiveRecord::Base has_and_belongs_to_many :games, :uniq => true end class Game < ActiveRecord::Base has_and_belongs_to_many :themes, :uniq => true end 
+7
ruby ruby-on-rails ruby-on-rails-3 associations
source share
4 answers

You should use database level validation:

 #new_migration add_index :games_themes, [:game_id, :theme_id], :unique => true 

HABTM

This will prevent duplicate data from being stored in the database. Takes load with Rails and guarantees you only a game or theme. The problem is that HABTM does not have a model, there is no check that you can perform in Rails, that is, you need to make it db-level

As mentioned in the comments, this means that you have to handle the exceptions raised from db as follows:

 #app/controllers/games_controller.rb def create #creation stuff here if @game.save #successful save else #capture errors end end 
+14
source share

Using:

 validates_uniqueness_of :theme_id, :scope => :game_id 

Properly:

 class Theme < ActiveRecord::Base has_many :games, through: :games_themes end class Game < ActiveRecord::Base has_many :themes, through: :games_themes end class GamesThemes < ActiveRecord::Base belongs_to :game belongs_to :theme validates_uniqueness_of :theme_id, :scope => :game_id end 
+4
source share

To perform checks in the connection table, you must use the has_many :through association. http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

+1
source share

Creating a new GameTheme model for verification purposes is not a good idea. We can affirm ourselves in the process of migration.

Thematic Model:

 class Theme < ActiveRecord::Base has_and_belongs_to_many :games, :association_foreign_key => 'theme_id', :class_name => 'Theme', :join_table => 'games_themes' end 

Game model:

 class Theme < ActiveRecord::Base has_and_belongs_to_many :games, :association_foreign_key => 'game_id', :class_name => 'Game', :join_table => 'games_themes' end 

games_themes mig: You can add uniqueness to the connection table, see here for more details.

 class GamesThemesTable < ActiveRecord::Migration def self.up create_table :games_themes, :id => false do |t| t.references :game t.references :theme end add_index :games_themes, [:theme_id, :game_id], :unique => true end def self.down drop_table :games_themes end end 
0
source share

All Articles