I have a 2 models Game
& Theme
and they have a has_and_belongs_to_many association. I have tried many solutions to prevent duplicate records in the games_themes
table, but no solutions work. The problem is, games_themes
is a table, but it is not a model, so I can't figure out a way to run validations on it effectively.
Heres a 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
You should use database-level validation:
#new_migration
add_index :games_themes, [:game_id, :theme_id], :unique => true
HABTM
This will prevent you saving any duplicate data in the database. Takes the burden off Rails & ensures you only have game or theme. The problem is because HABTM doesn't have a model, there's no validation you can perform in Rails, meaning you need to make it db-level
As mentioned in the comments, this means you'll have to handle the exceptions raised from the db like this:
#app/controllers/games_controller.rb
def create
#creation stuff here
if @game.save
#successful save
else
#capture errors
end
end
Use:
validates_uniqueness_of :theme_id, :scope => :game_id
As follows:
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
To run validations on join table you should use has_many :through
association instead.
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With