2016-04-29 38 views
1

我有沿此线的简单的ActiveRecord查询:如何通过与另一个模型实例进行比较来过滤ActiveRecord查询结果?

similar_changes = Notification.where(change_owner: 'foo1', change_target: 'foo2', change_cancelled: false) 

每个通知对象具有场change_type和我有检查一个通知的change_type与一种其他通知为逆的变化(即复原每个的变化的另一功能其他在我的申请中)。

我需要将此通知的change_type与数组中的所有其他数据进行比较。我必须像这样引用对象:similar_changes[0]['change_type']其中第一个索引是数组中的每个ActiveRecord,第二个是指定Notification对象中哪个属性的字典。

我有一种感觉,我能做到这一点有两个嵌套循环手动和if语句,但我也知道Ruby和我喜欢这种感觉是什么,它应该有内置的。

我错了,或者是有更好的方法来做到这一点?

下面是代码(注意,所有这些代码不会完全结束所以忍耐一下,如果它不是完美的):

def self.group_similar_changes(owner, target, change_type) 
    # long query where it selects all rows where change_owner and change_target 
    # are the same as original   
    # also where cancelled is false 
    # determine if cancelled (yaml) 
    # if cancelled (do nothing) 
    similar_changes = Notification.where(
    change_owner: owner, 
    change_target: target, 
    change_cancelled: false 
) 
    similar_changes.each do |change| 
    cancel_inverse_change(change, change.change_type) 
     if change.cancelled? 
     similar_changes.delete(change) 
     end 
    end 
    end 
end 

def cancel_inverse_change(change, change_type) 
    if change.inverse?(change_type) 
    change.cancel 
    end 
end 

def inverse?(possible_inverse_change) 
    is_inverse = false 
    change_types = YAML.load_file(File.join(NotificationManager::Engine.root, 'config/change_types.yaml')) 
    if self.change_type == change_types[possible_inverse_change]['inverse'] 
    is_inverse = true 
    end 
    return is_inverse 
end 
+0

没有,也没有神奇的红宝石这样做。使用循环。 – meagar

+1

“反向”来自哪里“返回反向”? 也change_types与change_type –

+0

啊,对不起。这是一个错字,很抱歉。 –

回答

1

是的,你的循环在similar_changes可以得到改善。

  • 修改你正在循环的数组令人困惑。我甚至不知道它是否可靠,因为我从不这样做!
  • 这也不是惯用的Ruby依靠each的返回值。 each通常用于对已存在的Enumerable的元素进行操作,因此使用它的返回值似乎很奇怪。

我把它写成

similar_changes.reject do |change| 
    cancel_inverse_change(change, change.change) 
    change.cancelled? 
end 
+0

我假设拒绝方法删除元素,如果它是T/F? –

+0

是的,“拒绝”会丢弃块返回true的元素。 –

+0

真棒,我会将这些工作到我的代码中,如果我能使它工作良好,我会选择答案。非常感谢您的反馈 :)。 –