2013-07-26 4 views
1

У меня есть приложение Rails 3.2, где Product - это модель. Product содержит атрибуты identifier, который никогда не имеет значения null и parent_identifier, что может быть нулевым. Отношения, когда они существуют, могут быть связаны цепями через многие поколения.Как я могу найти конечного предка в записи ActiveRecord, где parent_id не является обязательным?

Моя задача - скопировать ProductDetail объектов, has_many из Product, на последующие дочерние продукты.

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

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

* Примечание: Поле identifier не является первичным ключом, и это не практично, чтобы сделать так, как parent_identifier приходит из внешней базы данных и может даже не существует локально, если оно от до клиента подписался. Нецелесообразно проверять это при каждой нагрузке, так как ежедневно в день ежедневно будут храниться миллионы продуктов. *

+0

Говоря в терминах графика, это дерево? Или это просто один объект, наследующий от другого (если он не является корнем) –

+0

Это всегда одно наследование, поэтому оно не является деревом. Каждый лист может иметь только одного родителя, и каждый узел может иметь только один непосредственный ребенок. – AKWF

+0

И вам нужно захватить первый узел с деталями вверх по течению от последнего (leaf/current) [технически это также древовидный график;)] –

ответ

2

Если я правильно понимаю ваш запрос, следующие методы должны предоставить вам то, что вам нужно (ближайшая неточная коллекция ProductDetails вверх по течению).

class Product > ActiveRecord::Base 
    def parent 
    @parent ||= Product.where(identifier: self.parent_identifier).first 
    end 

    def parent_product_details 
    return unless parent 

    upstream_details = parent.product_details 
    upstream_details = parent.parent_product_details if upstream_details.empty? 

    upstream_details 
    end 
end 

Сообщите мне, если я неправильно понял проблему.

+1

Это отличное решение, и я подтвердил, что он работает. Благодаря! – AKWF