public
Last active

  • Download Gist
super.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
# * - Eqauls to
# / - Not equals to
# >, >=, <, <= works as expected
#
# Examples :
#
# Item.where(:colour * 'Red', :quanity > 10, :price <= 200)
# Post.where(:comments_count >= 1, :taggings_count < 5)
# User.where(:country / 'US') # Non american users
 
require "cases/helper"
require 'models/tag'
require 'models/tagging'
require 'models/post'
require 'models/topic'
require 'models/comment'
require 'models/reply'
require 'models/author'
require 'models/comment'
require 'models/entrant'
require 'models/developer'
require 'models/company'
 
class SuperCondition
attr_reader :operation, :value
 
def self.[](column, value, operation)
SuperCondition.new(column, value, operation)
end
 
def initialize(column, value, operation)
@column = column
@value = value
@operation = operation
end
 
def column
@column.to_s
end
end
 
class Symbol
def *(value)
SuperCondition[self, value, :eq]
end
 
def /(value)
SuperCondition[self, value, :neq]
end
 
def >(value)
SuperCondition[self, value, :gt]
end
 
def >=(value)
SuperCondition[self, value, :gte]
end
 
def <(value)
SuperCondition[self, value, :lt]
end
 
def <=(value)
SuperCondition[self, value, :lte]
end
end
 
module SuperWhere
extend ActiveSupport::Concern
 
included do
alias_method_chain :where, :power
end
 
def where_with_power(*args)
if Array.wrap(args).all? {|x| x.kind_of?(SuperCondition) }
conditions = []
 
args.each do |super_condition|
if super_condition.column.include?('.')
table, column = attr.split('.', 2)
table = @klass.connection.quote_table_name(table)
else
table, column = @klass.table_name, super_condition.column
end
 
quoted_column_name = "#{table}.#{@klass.connection.quote_column_name(column)}"
value = super_condition.value
 
conditions << case super_condition.operation
when :eq
where_clause = @klass.send(:attribute_condition, quoted_column_name, value)
replace_bind_variable(where_clause, value)
when :neq
replace_bind_variable("#{quoted_column_name} <> ?", value)
when :gt
replace_bind_variable("#{quoted_column_name} > ?", value)
when :gte
replace_bind_variable("#{quoted_column_name} >= ?", value)
when :lt
replace_bind_variable("#{quoted_column_name} < ?", value)
when :lte
replace_bind_variable("#{quoted_column_name} <= ?", value)
end
end
 
relation = spawn
conditions.each {|c| relation = relation.where(c) }
relation
else
where_without_power(*args)
end
end
 
private
 
def replace_bind_variable(clause, value)
@klass.send(:replace_bind_variables, clause, [value])
end
end
 
class ActiveRecord::Relation
include SuperWhere
end
 
class SuperRelationsTest < ActiveRecord::TestCase
fixtures :authors, :topics, :entrants, :developers, :companies, :developers_projects, :accounts, :categories, :categorizations, :posts, :comments,
:taggings
 
def test_sanity
assert_equal ["David"], Author.where(:name => 'David').map(&:name)
assert_equal ['Mary'], Author.where(["name = ?", 'Mary']).map(&:name)
assert_equal ['Mary'], Author.where("name = ?", 'Mary').map(&:name)
end
 
def test_super
puts Author.where(:name * 'David', :author_address_id > 2).to_sql
puts Post.where(:comments_count >= 1, :taggings_count < 5).to_sql
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.