Создание промежуточной модели для ассоциации has и belongs to many

#ruby-on-rails

#ruby-on-rails

Вопрос:

У меня есть has_and_belongs_to_many связь между двумя моделями.

 class DirectoryListing 
 has_and_belongs_to_many :directory_listing_categories

end

class DirectoryListingCategory
 has_and_belongs_to_many :directory_listings

end
  

Это создало две таблицы directory_listings и directory_listing_categories

и промежуточная третья таблица с именем directory_listing_categories_directory_listings

Я могу получить доступ к первым двум таблицам из консоли, используя запрос active record. Поскольку это отношение не создаст третью модель для промежуточной третьей таблицы, я не могу получить доступ к третьей промежуточной таблице из консоли rails.

Я пытался создать модель для этого, но безуспешно.

Правильный ли это способ доступа к третьей таблице?

 class DirectoryListingCategoryDirectoryListing < ActiveRecord::Base

end
  

Комментарии:

1. Если вы хотите иметь «промежуточную модель», почему бы вам не использовать has_many :through вместо has_and_belongs_to_many ?

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

3. У вас нет способа получить доступ к промежуточной модели с помощью has_and_belongs_to_many , так работает ассоциация. Если вы хотите что-то сделать с промежуточной моделью, вам нужно изменить ассоциацию has_many :through , других способов нет

Ответ №1:

Во-первых, для доступа к таблице в консоли в приложении должна быть создана модель с тем же именем, что и у таблицы.

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

 ActiveRecord::Base.connection.execute('your insert into query goes here')
  

Ответ №2:

Недавно я создал небольшое приложение, в котором мне пришлось хранить некоторые роли и сопоставлять их пользователям. Настройка была:

  1. User модель соответствует users таблице.
  2. Role модель соответствует roles таблице.
  3. Мне нужна была таблица для сопоставления «многие ко многим».

Миграция, которую я написал для создания таблицы ассоциаций, была примерно такой:

 class CreateUserRoleJoinTable < ActiveRecord::Migration[5.2]
  def up
    create_join_table :users, :roles
  end

  def down
    drop_join_table :users, :roles
  end
end
  

Когда вы запускаете миграцию, Rails создает roles_users . Если вы хотите, вы также можете добавить foreign_keys и уникальные индексы в up метод.

Модели похожи:

Пользователь

 class User < ApplicationRecord
  has_and_belongs_to_many :roles
end
  

Роль

 class Role < ApplicationRecord
  has_and_belongs_to_many :users
end
  

Таким образом, это более или менее тот же тип настройки.

Эта настройка предоставляет мне следующие методы для пользовательского объекта (представленные user объектом ниже:

  1. user.role_ids : Это принесет мне идентификаторы ролей, с которыми связан этот пользователь.
  2. user.role_ids= : Это позволит мне устанавливать роли для пользователей, используя как назначение, так и вставку массива. Вот так:
     user.role_ids = 1 # Assuming there are no roles already associated with the user
    user.role_ids = [2,6] # This will remove the previously assigned role (with ID = 1) and assign the roles with IDs 2 amp; 6 to the user
    user.role_ids << 5 # This will add the role ID 5 to the user (final role_ids at this point will be [2,5,6]
      
  3. user.roles : Это похоже на user.role_ids , но вместо идентификаторов я получу объекты роли.
  4. user.roles= : Опять же, аналогично user.role_ids= , но вместо идентификаторов будут использоваться объекты.

Аналогично для модели для подражания я получаю role.user_ids , role.user_ids= role.users , role.users= ,,,.

Дело в том, что мне редко, если вообще когда-либо, нужно прикасаться к roles_users таблице.

Если я это сделаю, я могу выполнить User.connection.execute(sql) и вручную прочитать результаты. В противном случае будет достаточно автоматически вводимых методов.

Я надеюсь, что это помогло.