2016-04-06 2 views
1

Я хочу взять модель ActiveRecord и фильтровать ассоциации вплоть до верхнего уровня, чтобы вложенные ассоциации, соответствующие определенному условию, не позволяли родителям находиться внутри возвращенных записей.Запрос ActiveRecord для фильтрации вложенных ассоциаций has_many

Позвольте мне объяснить это лучше. У меня есть следующие модели:

class SuperCategory < ActiveRecord::Base 
    attr_accessible :name 
    has_many :categories 
end 

class Category < ActiveRecord::Base 
    attr_accessible :name 
    belongs_to :super_category 
    has_many :sub_categories 
    has_many :books 
end 

class SubCategory < ActiveRecord::Base 
    attr_accessible :name 
    belongs_to :category 
    has_many :books 
end 

class Book < ActiveRecord::Base 
    belongs_to :sub_category 
    belongs_to :category 
    attr_accessible :show_me #boolean 
end 

В SuperCategoriesController, у меня есть:

class SuperCategoriesController < ApplicationController 
    def index 
    @super_categories = SuperCategory.all #here is where I want to query 
    respond_with(@super_categories) 
    end 
end 

задерживаясь /super_categories.json конечной точкой, я получу то, что выглядит как это, которое все дерево в формате JSON, так как мой .jbuilder парциальный добавляет все вложенные ассоциации:

[ 
    { 
    name: "supercategory1", 
    categories: [ 
     { 
     name: "category1", 
     books: [ 
      { show_me: true }, 
      { show_me: true }, 
      { show_me: false } 
     ] 
     }, 
     { 
     name: "category2", 
     sub_categories: [ 
      { 
      name: "subcategory1", 
      books:[ 
       { show_me: false } 
      ] 
      } 
     ] 
     } 
    ] 
    }, 
    { 
    name: "supercategory2", 
    categories: [ 
     { 
     name: "category3", 
     books: [ 
      { show_me: false } 
     ] 
     } 
    ] 
    } 
] 

то, что я хотел бы сделать в контроллере, если я передать его параметры таким образом, что show_me = true, то я бы не хотел показывать ни одну из книг, подкатегорий, категорий и суперкатегорий, в которых есть книги с show_me == false. Вот то, что я пробовал:

class SuperCategoriesController < ApplicationController 
    def index 
    if params[:show_me] == true 
     @super_categories = SuperCategory.joins(:categories).joins(:sub_categories).where(:books => { show_me: true }) 
    end 
    respond_with(@super_categories) 
    end 
end 

Это приводит к ошибке, потому что я не знаю, как присоединиться к :categories:sub_categories к :books. То, что я хотел бы, чтобы результат:

[ 
    { 
    name: "supercategory1", 
    categories: [ 
     { 
     name: "category1", 
     books: [ 
      { show_me: true }, 
      { show_me: true } 
     ] 
     } 
    ] 
    } 
] 

В принципе, когда я называю @super_category.categories должен быть только те категории, которые гнездились книги, где show_me == true. Точно так же, если есть SubCategories с книгами, где show_me == true, он также должен вернуть их. Есть ли комбинация ActiveRecord от .joins и .where, которая меня туда достает?

ответ

1

Это должно работать:

SuperCategory.joins(categories: :books).where("books.show_me = ?", true) 
    & 
SuperCategory.joins(categories: :sub_categories, :books).where("books.show_me = ?", true) 
+0

Я получаю синтаксическую ошибку здесь из-за '' & –

+0

& не просто, разделяющей 2 чередуется в ответе нет необходимости добавлять его в код –

Смежные вопросы