Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HABTM duplicate records

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
like image 702
user2158382 Avatar asked Feb 20 '14 01:02

user2158382


3 Answers

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
like image 165
Richard Peck Avatar answered Nov 13 '22 00:11

Richard Peck


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
like image 41
Richard Jordan Avatar answered Nov 12 '22 23:11

Richard Jordan


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

like image 1
Pavel Pachkovsky Avatar answered Nov 12 '22 23:11

Pavel Pachkovsky