has_many: через вопросы - PullRequest
       22

has_many: через вопросы

6 голосов
/ 10 ноября 2009

Ранее я использовал has_and_belongs_to_many и преобразовал в has_many: through. Вот как выглядит список игр, в которые могут играть многие пользователи. С этим я могу сделать game.users и user.games ....:

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

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

class GameUser < ActiveRecord::Base
  belongs_to :game
  belongs_to :user
end

И моя миграция базы данных для таблицы соединений:

create_table :game_users, :id => false do |t|
      t.column :game_id, :integer
      t.column :user_id, :integer
      t.column :player_index, :integer
    end

Я не совсем уверен, что все это понял, пожалуйста, помогите мне проверить мои факты:

  1. Является ли зависимый =>: уничтожить правильно? Я хочу, чтобы запись в таблице присоединения 'game_users' была удалена, если либо игра, либо пользователь уничтожен - но я не хочу, чтобы пользователи удалялись, если игры удаляются, и наоборот .....?

  2. В поле uniq предполагается, что игры содержат только уникальных пользователей, а пользователи содержат только уникальные игры. Это правильно?

  3. Миграция базы данных, как и прежде, имеет: id => false. Это все еще правильно? Я попытался в консоли уничтожить игру и получил жалобы на отсутствие идентификатора ... поэтому я не догадываюсь и пытаюсь понять, почему.

Я нахожу рельсы активных ассоциаций записи очень запутанными. Я думаю, что они не должны быть!

1 Ответ

5 голосов
/ 10 ноября 2009

1: Да, это правильно

2: из документации по uniq :

Если true, дубликаты будут опущены из коллекции. Полезно в в сочетании с: через.

Итак, да, если вы стремитесь не получить ни одну и ту же игру в пользовательской коллекции игр, ни того же пользователя в пользовательской коллекции игры, это правильно. Это все объяснено здесь .

Однако это не помешает созданию дубликатов GameUsers. Для этого вам нужно будет использовать validates_ уникальность _of в GameUser-модели:

class GameUser < ActiveRecord::Base
  validates_uniqueness_of :game_id, :scope => :user_id
end

3: Нет, вы больше не хотите использовать: id => false. Переключившись с has_and_belongs_to_many на has_many: through, вы повысили свою таблицу соединений «многие ко многим» до полной модели - GameUser - для которой требуется собственный идентификатор.

Пока он старый, этот по-прежнему хорошая статья для понимания has_many: through.

...