RoR: "принадлежит_то_мани"? Головная боль ассоциации - PullRequest
0 голосов
/ 14 ноября 2009

Кажется, я не могу обернуть голову вокруг этого, поэтому я решил написать и посмотреть, может ли кто-нибудь помочь мне (извините за вопрос, если это оскорбительно просто: мне сложно сейчас!)

У меня есть эти модели:

order
service
customer

Я думаю, они говорят сами за себя: service - это то, что customer покупает, когда ставит order.

Хорошо.

Итак, естественно, я устанавливаю эти отношения:

# a customer can have many orders
class Customer
   has_many :orders
end

# an order belongs to a single customer and can have many services
class Order
   belongs_to :customer
   has_many :services
end

... но вот где я спотыкаюсь:

# a service can belong to many orders
class Service
   # belongs_to :order ???
end

Потому что мое понимание belongs_to заключается в том, что - если я положу его туда - служба может принадлежать только одному order (в поле ключа order_id будет только одно значение - в настоящее время нет - привязать его только к одному заказу, где он должен иметь возможность принадлежать ко многим заказам).

Что мне здесь не хватает?

Ответы [ 4 ]

1 голос
/ 14 ноября 2009

Есть два способа справиться с этим. Первое - это отношение многих ко многим. В этом случае вы используете отношение has_and_belongs_to_many в моделях Order и Service. Rails автоматически создаст таблицу соединений, которая управляет отношениями. Отношения выглядят так:

class Order
  has_and_belongs_to_many :services
end

class Service
  has_and_belongs_to_many :orders
end

Второй способ - самостоятельно управлять таблицей соединений через промежуточную модель. В этом случае у вас может быть другая модель под названием «LineItem», которая представляет Сервис в контексте Заказа. Отношения выглядят так:

class LineItem
  belongs_to :order
  belongs_to :service
end

class Order
  has_many :line_items
end

class Service
  has_many :line_items
end

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

1 голос
/ 14 ноября 2009

Я думаю этот Railscast поможет вам - в основном у вас есть 2 варианта. Вы можете использовать has_and_belongs_to_many или has_many :through.

Вы также обнаружите, что has_and_belongs_to_many устарел в пользу has_many :though => model_name, который предоставляет ту же (и более) функциональность.

1 голос
/ 14 ноября 2009
class Customer
   has_many :orders
end

class Service
   has_many :orders
end

class Order
   belongs_to :customer
   belongs_to :service
end

Орден должен иметь customer_id и service_id, потому что он находится в отношениях многих к одному с обоими.

0 голосов
/ 14 ноября 2009

Я думаю, что вы поняли это, но ваш заказ на самом деле является моделью составного домена, иногда называемой агрегатной в DDD.

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

Совокупность, как сказал кто-то еще, состоит из заголовка, Заказа, который включает в себя такие вещи, как, кто заказал, дату, включает ли он налоги, стоимость доставки и т. Д. И у Ордена есть множество элементов OrderLineItem. Элемент OrderLineItem принадлежит к Сервису и содержит такие вещи, как заказанное количество, относится к товару / услуге и т. Д.

класс Customer

класс Order

класс OrderLineItem

Лично я использую имя модели OrderLineItem в отличие от LineItem, поскольку в системе, в которой необходимо отгружать реальные продукты, в отличие от услуг, у вас могут быть ассигнования, которые связывают заказы с запасами, которые будут иметь позиции и отгрузки, которые получают выделенные ресурсы. продукт для клиента, который также имеет позиции. Таким образом, термин позиции может быть перегружен. Скорее всего, это не так в вашей модели, потому что вы делаете только услуги.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...