2016-11-19 24 views
1

我不确定我是不是在搜索正确的东西,但我正在设置一个作用域,然后用作选择框的集合。使用嵌套对象的ActiveRecord作用域

笔记本型号:

class Notebook < ActiveRecord::Base 
    has_many :notes 
end 

注型号:

class Note < ActiveRecord::Base 
    belongs_to :notebook 
end 

我有一记几个属性,最重要的属性(这)是note_type。目前,note_type可以是check_list,textbookmark

我的目标是有这样的事情工作:

Notebooks.notes_without_check_lists 

来缩小范围,以便用户可以从下拉笔记本电脑不包含任何notesnote_typecheck_list 。我只是不确定我应该在每个note上进行迭代,以确定它的父代notebook是否可以包含在集合中。

编辑
目前,我有4个Notebook记录。在四条记录中,只有一条记录的票据类型为check_list。该笔记本共有两个笔记,其中只有一个笔记类型为check_list。因为这是真的,所以我想排除整个笔记本的范围,而不管笔记本中的其他笔记。

任何帮助肯定是赞赏。

回答

0

使用scope

class Notebook < ActiveRecord::Base 
    has_many :notes 
    scope :notes_without_check_lists, -> { joins(:notes).where.not(notes: { note_type: 'check_list' }).group('notebooks.id') } 
end 

基本上你执行数据库查询拉动所有的笔记本电脑的笔记,其中note_type不等于check_list

编辑

后您编辑的问题,这里是用Ruby(低效的notebooks/notes处理大集合)的解决方案 - 将仍然想用ActiveRecord解决它:

class Notebook < ActiveRecord::Base 
    has_many :notes 

    def self.notes_without_check_lists 
    all.reject { |notebook| notebook.notes.any? { |note| note.note_type == 'check_list' } } 
    end 
end 
+0

我认为这是非常接近的。但是,实际上我获得的记录数量比我在数据库中的总数还多。例如,我总共有4个笔记本对象,其中只有一个实际上包含带有检查列表的笔记。这是返回所有四个记录,再加上第三个记录的副本。我正在做更多的调查,但想要感谢您至少在某处使用此代码。 – gr8

+0

如果我使用'joins(:notes).where(注意:{note_type:'check_list'})',我得到一个包含检查列表的记录,所以按照预期的方式以相反的方式工作。 – gr8

+0

@jeepagooster我编辑了答案,注意'group'部分。如果这样做(它会100%)确保接受答案(寻找答案分数附近的复选标记) –