has_many: через создание дубликатов в соединительной таблице - PullRequest
1 голос
/ 17 сентября 2011

Я создал 3 модели, User, City, UserCity.

Класс пользователя:

class User < ActiveRecord::Base
  has_many :user_cities, :dependent => :destroy, :uniq => true
  has_many :cities, :through => :user_cities
end

Класс города:

class City < ActiveRecord::Base
  has_many :user_cities, :dependent => :destroy, :uniq => true
  has_many :users, :through => :user_cities
end

Класс UserCity:

class UserCity < ActiveRecord::Base
  belongs_to :user
  belongs_to :city
end

И тогда я попытался

u = User.new()
c = City.new()
u.cities << c
c.users << u
p UserCity.all.size # => 2

Таблица user_cities содержала дубликаты.Итак, я закодировал

класс UserCity:

class UserCity < ActiveRecord::Base
  validates :user_id, :uniqueness => {:scope => :city_id}
  belongs_to :user
  belongs_to :city
end

и запустил тот же код ruby, что и выше.Но это не удалось после c.users << u, потому что я запретил дублирование.

Как я могу заставить u.cities иметь c и c.users иметь u без дублирования данных в таблице соединения?


Добавлено:

Итак, если я выберу только c.users << u, могу ли я сделать это только для cities?

cities = Array.new()
UserCity.where(:user_id => u.id).each do |uc|
  cities << City.find(uc.city_id)
end

Ответы [ 2 ]

2 голосов
/ 17 сентября 2011

Выберите либо u.cities << c, либо c.users << u. Каждый из них вызывает строку, вставленную в таблицу соединения.

0 голосов
/ 19 июня 2017

Возможно, вы также захотите предотвратить дублирование в БД, добавив в БД индекс, который вызовет ошибку, если вы случайно попытаетесь добавить дублирующую запись объединения.Сделайте что-то подобное в миграции:

add_index :cities_users, [:city_id, :user_id], unique: true
...