Нормализация данных


(Bogdan) #1

Всех приветствую!
Вобщем ситуация такая: есть таблица Orders, эта таблица может иметь от одного или более ServiceTypes, через таблицу Services, вот набросок, надеюсь будет понятно:

В Services создается запись по каждому ордеру, а если еще ордер включает более одной услуги… Получается дикое дублирование данных. Думаю может в таблице Сервайсес переименовать поле order_id в group_service_type_id, и при каждом изменении таблицы ServiceTypes делать перекомпиляцию таблицы Services примерно так:
group_service_type_id | service_type_id
1 | 1
2 | 2
3 | 3
4 | 1
4 | 2
5 | 1
5 | 3
6 | 1
6 | 2
6 | 3

Т.е сделать группировку комбинаций услуг, и в параметрах проверять какой пакет услуг выбрал кастомер, к примеру: выбор [“Service1”, “Service3”], из таблицы group_service_type_id извлекается айдишник по этой комбинации: 5 и подставляется в заказ. По моему я видел что то похожее в Wordpress структуре БД, а может нет. В общем какие варианты решения данной проблемы.


(Kvokka) #2

class Order < AR::Base
has_many :services
has_many :service_types, throw: :services # если надо, укажи ,class_name: ‘my_conntction_class_name’, table_name: 'services’
has_many :own_service_types, class: 'ServiceTypes’
validates :services, length: {minimum: 1}

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

def group_services(*args)
Array(args).each_with_object({}){|e,a| a << e.service_types }.flatten.uniq.sort

можно на AR сделать, если выборка большая

end

быть может чтот типа такого хотелось?

def all_service_types
own_service_types + service_types
end

перекомпилировать или еще как-то мудрить тут не нужно.
имена не идеальные, ибо писано за несколько минут


#3

тебе тут нужно для нормлизации несколько табличек

  • orders - заказы
  • service - услуги
  • service_group - группировка услуг
  • service_group_relations - связь услуги с группой
  • order_group_relations - связь заказа с группой

никаких непотянтых перекомпиляций делать не нужно. вешай foreign_key с нужными constraints.
про has_many/has_one through тебе уже сверху kvokka намекнул. не понятно -чекни доку, в доке все досконально описано.
на основе связей у тебя будут доступны все сущности отовсюду в нужных местах в стиле ActiveRecord типа order.groups, order.services, service.group, group.orders, group.services, etc. в SQL у тебя здесь простейший join.

много данных и тормоза - подумай об индексах.


(Bogdan) #4

До конца логика не ясна, а можешь привести поля и связи этих двух таблиц?


(Bogdan) #5

Это еще таблица? Можно по подробнее, поля и связи какие у нее?


(Bogdan) #6

А все понял, class_name это фактическое определение таблицы


(Kvokka) #7

это таблица для HABTM, но для подробностебе тебе в рельсовый мануал или гугл

class_name- дабы вручную задать в каком классе она живет
table_name -дабы задать имя физической таблицы. если все по-соглашению делаешь, то не акктуально


(Bogdan) #8

А в чем различие промежуточной таблицы которая живет в объектной системе AR, и физической(HMT), проблему это не решает, мне нужно чтобы при создании Ордера если такой пакет услуг заказывали ранее то их не создавать а просто вернуть айдишник этой группы


(Kvokka) #9

когда ты создаешь HABTM то так же создается промежуточная таблица, только к ней доступа нет.
А так ее можно еще дополнительно настроить как хочется.

а так-то в чем проблема в контроллере проверять Order.find(params[:id]).services.where(name: 'order_name').empty? ну или как-то так.

Ну а по-хорошему сделать какие–то шорткаты на такие запросы в соответствующих моделях.


(Bogdan) #10

Вобщем-то понятно, еще хотелось бы послушать DaiveR’a по его структуре, я тут опять набросал, но опять остались вопросы:

модели:

class Order < ActiveRecord::Base
  has_many :order_group_relations
  has_many :service_groups, through: :order_group_relations
end

class OrderGroupRelation < ActiveRecord::Base
  belongs_to :order
  belongs_to :service_group
end

class Service < ActiveRecord::Base
  has_many :service_group_relations
  has_many :service_groups, through: :service_group_relations
end

class ServiceGroupRelation < ActiveRecord::Base
  belongs_to :service
  belongs_to :service_group
end

class ServiceGroup < ActiveRecord::Base
 ???
end

Что-то мне подсказывает что такая структура слишком перегружена, и что кстати в ServiceGroups, какие поля?


(Trump Clone) #12

пишу со своего саб-аккаунта (это daiver). сегодня после работы распишу идею. на самом деле все довольно просто))