Created
December 25, 2017 09:36
-
-
Save anoworl/7ee38c2bba0f4d20b8adc20b6b6e4a12 to your computer and use it in GitHub Desktop.
deep_unscope for Rails 4 to config/initializers/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ActiveRecord::QueryMethods | |
def deep_unscope(*args) | |
spawn.deep_unscope! *args | |
end | |
def deep_unscope_rel(rel, target_values) | |
case rel | |
when Arel::Nodes::Grouping | |
new_rel = deep_unscope_rel rel.expr, target_values | |
case new_rel | |
when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual | |
return new_rel | |
when nil | |
return nil | |
else | |
Arel::Nodes::Grouping.new new_rel | |
end | |
when Arel::Nodes::Or | |
left = deep_unscope_rel rel.left, target_values | |
right = deep_unscope_rel rel.right, target_values | |
if left and right | |
return Arel::Nodes::Or.new left, right | |
else | |
return left || right | |
end | |
when Arel::Nodes::And | |
children = rel.children.dup | |
children = children.map do |child| | |
deep_unscope_rel child, target_values | |
end.compact | |
case children.size | |
when 0 | |
return nil | |
when 1 | |
return children.first | |
else | |
return Arel::Nodes::And.new children | |
end | |
when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual | |
subrelation = (rel.left.kind_of?(Arel::Attributes::Attribute) ? rel.left : rel.right) | |
if target_values.include? subrelation.name.to_s | |
return nil | |
else | |
return rel | |
end | |
else | |
return rel | |
end | |
end | |
def deep_unscope!(*target_values) | |
target_values = target_values.map(&:to_s) | |
self.where_values = self.where_values.map do |rel| | |
deep_unscope_rel rel, target_values | |
end.compact | |
bind_values.reject! { |col,_| target_values.include? col.name } | |
self | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment