Рельсовые отношения - PullRequest
       4

Рельсовые отношения

2 голосов
/ 29 марта 2011

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

У меня есть модель Project и модель Client.Проект belongs_to :client => Мне нужно вручную добавить client_id в таблицу проектов (с миграцией).
A Client has_many :projects => Мне не нужно ничего делать в БД (без миграции),Доступны оба метода project.client и client.projects.

У меня есть модель Group и модель User.
A Group has_and_belongs_to_many :user
A Userhas_and_belongs_to_many :group Затем мне нужно создать миграцию для создания объединенной таблицы с указателями user_id и group_id.

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

Иногда я теряюсь:)

Спасибо и С уважением,

Люк

Ответы [ 2 ]

5 голосов
/ 29 марта 2011

Для ассоциации has_many <-> belongs_to вы определяете, что один проект принадлежит (belongs_to) одному клиенту.Следовательно, у этого клиента есть много (has_many) проектов.Для того чтобы проект определил, к какому клиенту он принадлежит, он должен иметь столбец client_id, чтобы он мог его найти.Этот столбец client_id используется Rails при вызове метода client, примерно так:

Client.find(project.client_id)

Вот так вы можете найти клиента проекта.Столбец client_id часто называют внешним ключом , поскольку он является уникальным идентификатором («ключом») в таблице не своего происхождения («чужой»).Boom.

Когда вы звоните наоборот, находя все проекты, которые есть у клиента, то есть client.projects, Rails делает эквивалент этого:

Project.find_all_by_client_id(client.id)

Это возвращает все Project записей, которые связаны с конкретным клиентом, на основе поля client_id в таблице projects.


С ассоциацией has_and_belongs_to_many, такой как пример пользователей и групп, выобъявляете, что пользователь has_and_belongs_to_many :groups.

Теперь, если бы это был просто has_many :groups, внешний ключ был бы в таблице groups, или если бы это был belongs_to, он бы вошел в таблицу users.Хорошо помнить: внешний ключ всегда помещается в таблицу модели с belongs_to.

. Вы также объявляете, что группа has_and_belongs_to_many :users, и поэтому мы сталкиваемся с той же проблемой.Мы не можем объявить ключ в таблице пользователей, потому что он не принадлежит ему (поскольку у пользователя много групп, вам нужно будет сохранить все идентификаторы групп, к которым он принадлежит) или таблицу групп по тем же причинам.

Вот почему для has_and_belongs_to_many нам нужно создать так называемую таблицу соединений .Эта таблица имеет два и только два поля (оба являются внешними ключами), одно для одной стороны ассоциации и другое для другой.Чтобы создать эту таблицу, мы поместили бы ее в метод миграции self.up:

create_table :groups_users, :id => false do |t|
  t.integer :group_id
  t.integer :user_id
end

Здесь необходимо отметить пару вещей:

  1. Имя таблицы - это два именииз двух ассоциаций в алфавитном порядке.G предшествует U, поэтому имя таблицы равно groups_users.
  2. Здесь есть опция :id, которая при задании значения false создает таблицу без первичного ключа.Таблица соединения не нуждается в первичном ключе, потому что ее цель состоит в том, чтобы просто объединить другие таблицы.
  3. Мы храним group_id и user_id как целочисленные поля, как мы это делаем для belongs_toассоциация.

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

Нет необходимости определять дополнительные столбцы для users или groupstable, потому что таблица соединения получает это под контроль.

0 голосов
/ 09 апреля 2014
class Customer < ActiveRecord::Base
  has_many :orders, dependent: :destroy
end

class Order < ActiveRecord::Base
  belongs_to :customer
end

@order = @customer.orders.create(order_date: Time.now)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...