I'm trying to implement a two-way has_many :through
association between a User model and a Location model using a UserLocations join table. This will enable setting user locations with built in ActiveRecord methods, ie. @user.locations = [<Location 1>, <Location 2>, ...]
. My goal is to not associate locations to users individually, but rather for users to add and remove them, one or more at a time, via another field: :zip_code
. This means that when a user adds a zip code, ActiveRecord should insert a single record into UserLocations (something like INSERT INTO user_locations (user_id, zip_code) VALUES (1, 12345)
). Then, when @user.locations
is called, ActiveRecord should join by :zip_code
and get the matching location(s). My current implementation works, except that one INSERT
into UserLocations is generated for each location associated with a zip code.
class User < ActiveRecord::Base
has_many :user_locations
has_many :locations, through: :user_locations
end
class UserLocation < ActiveRecord::Base
belongs_to :user
belongs_to :location, primary_key: :zip_code, foreign_key: :zip_code
end
class Location < ActiveRecord::Base
has_many :user_locations, primary_key: :zip_code, foreign_key: :zip_code
has_many :users, through: :user_locations
end
Things I've tried:
validates_uniqueness_of :zip_code, scope: :user_id
- just throws a validation error and prevents all record creationhas_many unique: true
- doesn't prevent duplicate DB queriesadd_index unique: true
for(user_id, zip_code)
- would at least prevent duplicate entries from being created, but I'm trying to prevent unnecessary queries entirely
Using questions like this one for guidance hasn't gotten me any closer. Is what I'm trying to do possible without using my own methods to get/set user locations?