0

У меня есть рекурсивная древовидная структура для обработки моих категорий. Каждая категория листьев может иметь ноль или более сделок. Категории определяетсяПолучить атрибуты детей в рекурсивной древовидной структуре, если это не листовой узел

class Category < ActiveRecord::Base 
    has_many :sub_categories, class_name: "Category", foreign_key: "parent_category_id" 
    belongs_to :parent_category, class_name: "Category" 

    has_many :deal_categories 
    has_many :deals, through: :deal_categories 

    def leaf? 
    !has_sub_categories? 
    end 

    def has_sub_categories? 
    !sub_categories.empty? 
    end 
end 

Deals и DealCategories выглядит следующим образом:

class Deal < ActiveRecord::Base 
    has_many :deal_categories 
    has_many :categories, through: :deal_categories 
end 

class DealCategory < ActiveRecord::Base 
    belongs_to :deal 
    belongs_to :category 
end 

Есть также некоторые валидация, убедившись, что Deals только могут существовать в виде листьев категорий. Таким образом, если я вызываю category.deals на листовом узле, я получаю некоторые сделки, и если я его вызываю на корневом узле, я получаю пустой результат. Все хорошо.

Но теперь я хочу category.deals, чтобы возвращать сделки своих детей, если это не корневой узел. Мой подход был переопределить следующий метод в моем классе Category следующим образом:

alias_method :original_deals, :deals 
    def deals 
    if leaf? 
     self.original_deals 
    else 
     self.sub_categories.deals 
    end 
    end 

Это, однако, не работает, как я не могу назвать deals непосредственно на sub_categories, ошибка будучи

undefined method `deals' for #<Category::ActiveRecord_Associations_CollectionProxy:0x00000009243d40> 

Как я решаю это?

ответ

0

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

sub_categories.reduce([]) { |union, sub_category| union + sub_category.deals } 

Использования уменьшить создает памятку объект (представленный переменный союз), и оценка блока становятся новым объектом памятки. Я начинаю с пустого массива и добавляю результат вызова сделок по каждой sub_category в вашей коллекции sub_categories.