Rails принадлежит_to и has_many одной модели - PullRequest
1 голос
/ 08 мая 2020

Я пытаюсь создать схему базы данных в рельсах между двумя моделями Пользователи и Круги . Круг - это определенная пользователем группа, известная только тому пользователю, который ее создал. Круг содержит других пользователей, которых пользователь выбрал для включения в этот круг, и имя круга.

Итак, мое решение следующее:

  1. Модель пользователей: has_many: Круги
  2. Модель кругов: принадлежит_to: Пользователь , has_many: Users

Я знаю, что существует метод от has_many до , но я не знаю, нужно ли это в моем случае.

1 Ответ

1 голос
/ 08 мая 2020

На самом деле вам нужны две разные ассоциации. Первая - это ассоциация "один ко многим". Ленивый способ его настройки:

class Circle < ApplicationRecord
  belongs_to :user
end


class User < ApplicationRecord
  has_many :circles
end

Это связывает пользователей с кругами через столбец внешнего ключа user_id на кругах. Но это довольно неоднозначно - что означает user.circles? Это круги, созданные пользователем, или те, в которых он состоит? Лучше быть более явным, даже если для этого потребуется некоторая конфигурация:

class RenameUserToCreator < ActiveRecord::Migration[6.0]
  def change
    rename_column :circles, :user_id, :creator_id
  end
end

# rails g model circle 
class Circle < ApplicationRecord
  belongs_to :creator, class_name: 'User'
end


class User < ApplicationRecord
  has_many :created_circles, 
    class_name: 'Circle',
    foreign_key: :creator_id
end

Затем вы хотите добавить участников в круг. Это ассоциация «многие ко многим», которую можно выполнить с помощью has_many through: или has_or_belongs_to_many. Оба используют объединяющую таблицу, но has_or_belongs_to_many не имеет модели и его реальная полезность очень ограничена. При именовании таблиц соединения ленивые соглашения заключаются в том, чтобы просто использовать объединение a & b - CircleUser, но используйте лучшее имя, если вы можете придумать имя, которое подходит для домена.

class Circle
  belongs_to :creator, class_name: 'User'
  has_many :memberships
  has_many :users, through: :memberships
end

# rails g model membership user:belongs_to circle:belongs_to
class Membership
  belongs_to :user
  belongs_to :circle
end

class User
  has_many :created_circles, 
    class_name: 'Circle',
    foreign_key: :creator_id
  has_many :memberships
  has_many :circles, through: :memberships
end

Одна вещь, чтобы имейте в виду, что каждая ассоциация ДОЛЖНА иметь уникальное имя. Если бы мы не go выполнили предыдущий шаг и написали:

class User
  has_many :circles
  has_many :memberships
  has_many :circles, through: :memberships
end

Последняя ассоциация просто заткнет предыдущую ассоциацию.

...