def rebuild_condition_options!
conds = []
binds = {}
used_paths = Set.new
delete_paths = Set.new
obligation_conditions.each_with_index do |array, obligation_index|
obligation, conditions = array
obligation_conds = []
conditions.each do |path, expressions|
model = model_for( path )
table_alias = table_alias_for(path)
parent_model = (path.length > 1 ? model_for(path[0..-2]) : top_level_model)
expressions.each do |expression|
attribute, operator, value = expression
if attribute == :id and operator == :is and parent_model.columns_hash["#{path.last}_id"]
attribute_name = "#{path.last}_id""#{path.last}_id"
attribute_table_alias = table_alias_for(path[0..-2])
used_paths << path[0..-2]
delete_paths << path
else
attribute_name = model.columns_hash["#{attribute}_id"] && "#{attribute}_id""#{attribute}_id" ||
model.columns_hash[attribute.to_s] && attribute ||
:id
attribute_table_alias = table_alias
used_paths << path
end
bindvar = "#{attribute_table_alias}__#{attribute_name}_#{obligation_index}".to_sym
sql_attribute = "#{parent_model.connection.quote_table_name(attribute_table_alias)}." +
"#{parent_model.connection.quote_table_name(attribute_name)}"
if value.nil? and [:is, :is_not].include?(operator)
obligation_conds << "#{sql_attribute} IS #{[:contains, :is].include?(operator) ? '' : 'NOT '}NULL"
else
attribute_operator = case operator
when :contains, :is then "= :#{bindvar}"
when :does_not_contain, :is_not then "<> :#{bindvar}"
when :is_in, :intersects_with then "IN (:#{bindvar})"
when :is_not_in then "NOT IN (:#{bindvar})"
when :lt then "< :#{bindvar}"
when :lte then "<= :#{bindvar}"
when :gt then "> :#{bindvar}"
when :gte then ">= :#{bindvar}"
else raise AuthorizationUsageError, "Unknown operator: #{operator}"
end
obligation_conds << "#{sql_attribute} #{attribute_operator}"
binds[bindvar] = attribute_value(value)
end
end
end
obligation_conds << "1=1" if obligation_conds.empty?
conds << "(#{obligation_conds.join(' AND ')})"
end
(delete_paths - used_paths).each {|path| reflections.delete(path)}
finder_options[:conditions] = [ conds.join( " OR " ), binds ]
end