TL; DR: У меня есть модель, которая belongs_to :group
, где group
- это еще один экземпляр той же модели. У этого «родителя» group
также может быть родитель, и так далее по цепочке. Есть ли способ до includes
этой структуры, насколько это возможно?
У меня есть модель Location
, которая выглядит следующим образом (сокращенная версия):
create_table "locations", force: :cascade do |t|
t.string "name"
t.decimal "lat", precision: 20, scale: 15
t.decimal "long", precision: 20, scale: 15
t.bigint "group_id"
t.string "type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["group_id"], name: "index_locations_on_group_id"
end
class Location < ApplicationRecord
belongs_to :group, class_name: 'Location', required: false
has_many :locations, foreign_key: 'group_id', dependent: :destroy
end
Другими словами, он может необязательно принадлежать «родительскому» экземпляру самого себя, обозначаемому как group
.
Этот родительский экземпляр также может принадлежать родительскому экземпляру на другой уровень выше, как и его родительский и т. Д. И т. Д. Слоны, вплоть до нижнего уровня.
То, что я хотел бы сделать, это связать вместе имена Локации и всех ее родительских экземпляров, поэтому я получаю что-то вроде "Top-level group > Mid-level group > Lowest group > Location"
. Это хорошо, и я уже реализовал это в модели:
def parent_chain
Enumerator.new do |enum|
parent_group = group
while parent_group != nil
enum.yield parent_group
parent_group = parent_group.group
end
end
end
def name_chain
(parent_chain.map(&:name).reverse + [name]).join(" \u00BB ")
end
Единственная проблема с этим, однако, заключается в том, что он будет запрашивать индивидуально для каждого родительского экземпляра по мере его поступления (проблема N + 1). Как только я включаю несколько локаций на одной странице, это много запросов, замедляющих загрузку. Я хотел бы предварительно загрузить (через includes
) эту структуру, как для обычной belongs_to
ассоциации, но я не знаю, есть ли способ включить произвольное число родителей, подобных этому.
Есть? Как мне это сделать?