Pull to refresh

Comments 18

UFO just landed and posted this here
Примеры фактори:

FactoryGirl.define do
  factory :truck do
  end

  factory :ship do
  end

  factory :location do
    trait :with_truck do
      after(:build) { |l| l.trucks << FactoryGirl.build(:truck) }
    end

    trait :with_ship do
      after(:build) { |l| l.ships << FactoryGirl.build(:ship) }
    end
  end
end
извините, я не понимаю, чем тут не работает многие-ко-многим?
просто Depricated. Плюс при has_many -> has_many в соеденительной таблице можно сохранить доп. аттрибуты.
вот это новости…
в официальном гайде про это не слова. можно ли пруфлинк?
про доп. атрибуты понятно, само собой.
в guides нашёл заметку «The use of extra attributes on the join table in a has_and_belongs_to_many association is deprecated».

пруфлинк: github.com/rails/rails/blob/v4.0.2/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb#L22
Но интересно другое. В новой версии о deprecation речи не идёт… github.com/rails/rails/blob/master/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
так вопрос не про доп атрибуты, а про deprecated связей многие-ко-многим, как я понял из вашего комментария.
да, перечитал — мой косяк.
has_and_belongs_to_many по сути использует промежуточную таблицу. Что в результате выльется в 4 таблицы trains_locations, ships_locations, copters_locations, trucks_locations
и что с того?
само по себе увеличение количества таблиц не есть плохо. иначе все пихали бы в одну большую таблицу.
действительно, код с полиморфными связями несколько более элегантен (абстрактно), но с практической точки зрения это ничего не дает. с точки зрения производительности, непонятно, что же лучше, связи многие-ко-многим или или полиморфные связи в данном случае. некоторое отклонение от DRY может быть очень даже к месту.

я бы обошелся в данном конкретном варианте именно n-to-n связми, поскольку, как мне кажется, у этих таблицу будут физически разные пользователи, которые будут нагружать эти таблицы неравномерно (вероятно). а значит, когда вопрос коснется оптимизации, кеширования и настройки производительности, вам будет легче это делать с разными таблицами, а не с одной. в т.ч. разносить их физически и даже делить таблицу location на четыре части, если потребуется.
в противном случае, если мое допущение неверно, я бы сделал STI, как правильно отметили ниже.

конечно, все это сделать можно и с полиморфными связями, нет ничего не возможного, но человеко-часы не бесплатны и не бесконечны.
Для выше приведенного кейса, когда выделяются классы TrainLocation, CopterLocation и т.д., удобней использовать STI. Так как реляционные БД не поддерживают наследование, а хранение каждого класса в отдельной таблице увеличивате количество JOIN`ов, используется паттерн «Наследование с единой таблицей» — поля всех классов иерархии записываются в одну таблицу.
Плюс вам. Более того тут возможно (сильно зависит от контекста, но в данном случае вполне) использовать STI и для самих типов транспорта. Это бы все упростило.
Если модели видов транспорта будут иметь множество разношерстных атрибутов (уникальных для каждой модели), то sti — уже будет неудачным вариантом.
Если бы я решал задачу, то скорее всего сделал бы как вы, но:
1) Вместо MoveableLocation попытался бы выделить какие-то общие характеристики из всех типов транспорта и получил бы сущность Carrier. Эта сущность как раз бы и имела полиморфную связь на Train, Copter и так далее.

2) Если общие характеристики выделить не получается или их слишком мало, то действительно нужно воспользоваться STI (как уже писали выше).
Хорошее решение, пример конечно можно решить и через has_many through. Но на самом деле бывают другие причины использования сквозных ассоциаций с полиморфными связями. Я из этого поста извлек пользу того как можно сделать has_many through если source полиморфная ассоциация. Спасибо за статью!
Схема красивая. В Фотошопе рисовалась или есть какая-то чудесная прога, которая умеет такие схемы конструировать?
Sign up to leave a comment.

Articles