inequal_opportunity 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/MIT-LICENSE +20 -0
- data/README +68 -0
- data/Rakefile +12 -0
- data/VERSION.yml +4 -0
- data/inequal_opportunity.gemspec +53 -0
- data/init.rb +4 -0
- data/lib/inequal_opportunity.rb +154 -0
- data/test/database.example.yml +8 -0
- data/test/db_setup.rb +13 -0
- data/test/inequal_opportunity_test.rb +175 -0
- data/test/test_helper.rb +4 -0
- metadata +75 -0
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Ryan Angilly
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
= Inequal Opportunity
|
2
|
+
|
3
|
+
inequal_opportunity exists because this does not work in ActiveRecord:
|
4
|
+
|
5
|
+
Doctor.all(:joins => :patients, :conditions => {:patients => ['age > ?', 20]})
|
6
|
+
|
7
|
+
You will get an unknown column exception looking for `doctors`.`age`.
|
8
|
+
Instead, you need to write:
|
9
|
+
|
10
|
+
Doctor.all(:joins => :pateints, :conditions => ['`patients`.`age` > ?', 20])
|
11
|
+
|
12
|
+
Putting the string table name in the query annoyed me. On top of that,
|
13
|
+
I always wanted a way to eliminate strings from my named scopes and queries.
|
14
|
+
So now with inequal_opportunity you can write:
|
15
|
+
|
16
|
+
Doctor.all(:joins => :patients, :conditions => {:patients => {:age => gt(20)}})
|
17
|
+
|
18
|
+
Not only is it prettier (hashed), but ActiveRecord will keep track of
|
19
|
+
table names for you.
|
20
|
+
|
21
|
+
ActiveRecord looks for Array and Range types to decide whether to use
|
22
|
+
'IN' or 'BETWEEN' instead of the normal '=' as the comparison operator
|
23
|
+
when generating SQL. inequal_opportunity extends that pattern by
|
24
|
+
wrapping the value in a series of ActiveRecord::Inequality::Base classes.
|
25
|
+
Just wrap the value with one of the following helper functions:
|
26
|
+
|
27
|
+
gte() => >=
|
28
|
+
gt() => >
|
29
|
+
lte() => <=
|
30
|
+
le() => <
|
31
|
+
ne() => <>
|
32
|
+
ne(nil) => IS NOT
|
33
|
+
|
34
|
+
and the appropriate SQL will be generated. This works in finds, as shown
|
35
|
+
above, in counts:
|
36
|
+
|
37
|
+
People.count(:age => gt(20))
|
38
|
+
|
39
|
+
in named scopes:
|
40
|
+
|
41
|
+
class People < AR::B
|
42
|
+
named_scope :underage, :conditions => {:age => lte(18)}
|
43
|
+
end
|
44
|
+
|
45
|
+
in default scopes:
|
46
|
+
|
47
|
+
class Feedback < AR::B
|
48
|
+
default_scope :conditions => {:type => ne('spam')}
|
49
|
+
end
|
50
|
+
|
51
|
+
and pretty much everywhere else I've tested manually.
|
52
|
+
|
53
|
+
Test coverage is kind of sparse right now, and it's only been tested
|
54
|
+
on MySQL. But it has been rock solid in every situation I've thrown it in,
|
55
|
+
so I figured the best way to improve it was to release the hounds (YOU).
|
56
|
+
|
57
|
+
Note that I am not completely satisfied with the way I alias
|
58
|
+
ActiveRecord::Base.expand_range_bind_variables. It smells, but it works.
|
59
|
+
Suggestions welcome.
|
60
|
+
|
61
|
+
== License
|
62
|
+
|
63
|
+
inequal_opportunity is released under the MIT license.
|
64
|
+
|
65
|
+
|
66
|
+
== Support
|
67
|
+
|
68
|
+
Just email me at ryan@angilly.com with questions, bugs, or patches.
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "inequal_opportunity"
|
5
|
+
gemspec.summary = "Adds mergable, stackable inequality statements to ActiveRecord conditions"
|
6
|
+
gemspec.email = "ryan@angilly.com"
|
7
|
+
gemspec.homepage = "http://github.com/ryana/inequal_opportunity"
|
8
|
+
gemspec.description = "Adds mergable, stackable inequality statements to ActiveRecord conditions"
|
9
|
+
gemspec.authors = ["Ryan Angilly"]
|
10
|
+
end
|
11
|
+
Jeweler::GemcutterTasks.new
|
12
|
+
end
|
data/VERSION.yml
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{inequal_opportunity}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ryan Angilly"]
|
12
|
+
s.date = %q{2010-05-18}
|
13
|
+
s.description = %q{Adds mergable, stackable inequality statements to ActiveRecord conditions}
|
14
|
+
s.email = %q{ryan@angilly.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"MIT-LICENSE",
|
21
|
+
"README",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION.yml",
|
24
|
+
"inequal_opportunity.gemspec",
|
25
|
+
"init.rb",
|
26
|
+
"lib/inequal_opportunity.rb",
|
27
|
+
"test/database.example.yml",
|
28
|
+
"test/db_setup.rb",
|
29
|
+
"test/inequal_opportunity_test.rb",
|
30
|
+
"test/test_helper.rb"
|
31
|
+
]
|
32
|
+
s.homepage = %q{http://github.com/ryana/inequal_opportunity}
|
33
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
s.rubygems_version = %q{1.3.6}
|
36
|
+
s.summary = %q{Adds mergable, stackable inequality statements to ActiveRecord conditions}
|
37
|
+
s.test_files = [
|
38
|
+
"test/db_setup.rb",
|
39
|
+
"test/inequal_opportunity_test.rb",
|
40
|
+
"test/test_helper.rb"
|
41
|
+
]
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
45
|
+
s.specification_version = 3
|
46
|
+
|
47
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
48
|
+
else
|
49
|
+
end
|
50
|
+
else
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
data/init.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Inequality
|
3
|
+
|
4
|
+
class InequalError < Exception
|
5
|
+
end
|
6
|
+
|
7
|
+
class Base
|
8
|
+
attr_accessor :value
|
9
|
+
|
10
|
+
def initialize(val)
|
11
|
+
self.value = val
|
12
|
+
end
|
13
|
+
|
14
|
+
def operator
|
15
|
+
raise('Nope')
|
16
|
+
end
|
17
|
+
|
18
|
+
def ==(val)
|
19
|
+
self.operator == val.operator && self.value == val.value
|
20
|
+
end
|
21
|
+
|
22
|
+
def string_value
|
23
|
+
value ? "'#{value}'" : 'nil'
|
24
|
+
end
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
" #{operator} #{self.string_value}"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
class GreaterThanEqual < Base
|
33
|
+
def operator
|
34
|
+
'>='
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class GreaterThan < Base
|
39
|
+
def operator
|
40
|
+
'>'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class LessThanEqual < Base
|
45
|
+
def operator
|
46
|
+
'<='
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class LessThan < Base
|
51
|
+
def operator
|
52
|
+
'<'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class NotEqual < Base
|
57
|
+
def operator
|
58
|
+
case value
|
59
|
+
when NilClass, TrueClass, FalseClass
|
60
|
+
'IS NOT'
|
61
|
+
when Array
|
62
|
+
'NOT IN'
|
63
|
+
else
|
64
|
+
'<>'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Like < Base
|
70
|
+
def operator
|
71
|
+
'LIKE'
|
72
|
+
end
|
73
|
+
|
74
|
+
# This method is why I love Ruby
|
75
|
+
def value(override = false)
|
76
|
+
v = super(*[])
|
77
|
+
|
78
|
+
if !override && !v.is_a?(Numeric) && !v.is_a?(String)
|
79
|
+
raise InequalError, "Passing #{v.class} to Like. You can't possibly want to do this"
|
80
|
+
end
|
81
|
+
|
82
|
+
"%#{v}%"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
module WrapperMethods
|
87
|
+
|
88
|
+
def lte(val)
|
89
|
+
ActiveRecord::Inequality::LessThanEqual.new(val)
|
90
|
+
end
|
91
|
+
|
92
|
+
def lt(val)
|
93
|
+
ActiveRecord::Inequality::LessThan.new(val)
|
94
|
+
end
|
95
|
+
|
96
|
+
def gte(val)
|
97
|
+
ActiveRecord::Inequality::GreaterThanEqual.new(val)
|
98
|
+
end
|
99
|
+
|
100
|
+
def gt(val)
|
101
|
+
ActiveRecord::Inequality::GreaterThan.new(val)
|
102
|
+
end
|
103
|
+
|
104
|
+
def ne(val)
|
105
|
+
ActiveRecord::Inequality::NotEqual.new(val)
|
106
|
+
end
|
107
|
+
|
108
|
+
def like(val)
|
109
|
+
ActiveRecord::Inequality::Like.new(val)
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
class Base
|
117
|
+
class << self
|
118
|
+
alias attribute_condition_orig attribute_condition
|
119
|
+
def attribute_condition(quoted_column_name, argument)
|
120
|
+
if argument.is_a? ActiveRecord::Inequality::Base
|
121
|
+
question = argument.value.is_a?(Array) ? '(?)' : '?'
|
122
|
+
"#{quoted_column_name} #{argument.operator} #{question}"
|
123
|
+
else
|
124
|
+
attribute_condition_orig(quoted_column_name, argument)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
alias expand_range_bind_variables_orig expand_range_bind_variables
|
129
|
+
def expand_range_bind_variables(bind_vars)
|
130
|
+
expanded = []
|
131
|
+
|
132
|
+
bind_vars.each do |var|
|
133
|
+
next if var.is_a?(Hash)
|
134
|
+
|
135
|
+
if var.is_a?(Range)
|
136
|
+
expanded << var.first
|
137
|
+
expanded << var.last
|
138
|
+
elsif var.is_a?(ActiveRecord::Inequality::Base)
|
139
|
+
expanded << var.value
|
140
|
+
else
|
141
|
+
expanded << var
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
expanded
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
include ActiveRecord::Inequality::WrapperMethods
|
154
|
+
|
data/test/db_setup.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
DB = YAML::load(File.open(File.join(File.dirname(__FILE__), 'database.yml'))).symbolize_keys!
|
2
|
+
ActiveRecord::Base.establish_connection(DB[:source])
|
3
|
+
|
4
|
+
TABLES = %w(mains seconds)
|
5
|
+
|
6
|
+
TABLES.each do |t|
|
7
|
+
ActiveRecord::Base.connection.execute("drop table if exists #{t};")
|
8
|
+
end
|
9
|
+
|
10
|
+
TABLES.each do |t|
|
11
|
+
ActiveRecord::Base.connection.execute("create table #{t} (id integer, val integer, seconds_id integer, mains_id integer, created_at datetime default null);")
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
require File.join(File.dirname(__FILE__), 'db_setup')
|
3
|
+
|
4
|
+
METHOD_SYMBOLS = [:gt, :gte, :lt, :lte, :ne, :like]
|
5
|
+
|
6
|
+
class Main < ActiveRecord::Base
|
7
|
+
belongs_to :seconds
|
8
|
+
named_scope :newer_than, lambda {|time| {:conditions => {:created_at => gte(time) }} }
|
9
|
+
|
10
|
+
METHOD_SYMBOLS.each do |s|
|
11
|
+
named_scope :"try_#{s}", lambda {|i| {:conditions => {:id => send(s, i)}} }
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class Second < ActiveRecord::Base
|
17
|
+
has_many :mains
|
18
|
+
end
|
19
|
+
|
20
|
+
class InequalOpportunityTest < Test::Unit::TestCase
|
21
|
+
|
22
|
+
def setup
|
23
|
+
TABLES.each do |t|
|
24
|
+
ActiveRecord::Base.connection.execute("DELETE FROM #{t};")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "a model" do
|
29
|
+
setup do
|
30
|
+
@model = Main
|
31
|
+
end
|
32
|
+
|
33
|
+
should "respond to gte" do
|
34
|
+
assert @model.respond_to?(:gte)
|
35
|
+
end
|
36
|
+
|
37
|
+
should "should work with a named_scope" do
|
38
|
+
assert_equal Main.newer_than(2.days.ago).all, []
|
39
|
+
end
|
40
|
+
|
41
|
+
should "generate proper sql for array" do
|
42
|
+
METHOD_SYMBOLS.each do |s|
|
43
|
+
|
44
|
+
if s == :ne
|
45
|
+
assert_equal Main.try_ne([1,2,3]).first, nil
|
46
|
+
elsif s == :like
|
47
|
+
assert_raises ActiveRecord::Inequality::InequalError do
|
48
|
+
assert_equal Main.try_like([1,2,3]).first, nil
|
49
|
+
end
|
50
|
+
else
|
51
|
+
assert_raises ActiveRecord::StatementInvalid do
|
52
|
+
assert_equal Main.send(:"try_#{s}", [1,2,3]).first, nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal Main.try_ne([1,2,3]).first, nil
|
58
|
+
assert_equal Main.try_ne([1,2,3]).count, 0
|
59
|
+
end
|
60
|
+
|
61
|
+
should "generate proper sql for nil and not nil" do
|
62
|
+
METHOD_SYMBOLS.each do |s|
|
63
|
+
assert_equal Main.send(:"try_#{s}", 1).first, nil
|
64
|
+
assert_equal Main.send(:"try_#{s}", nil).first, nil unless s == :like
|
65
|
+
end
|
66
|
+
|
67
|
+
assert_raises ActiveRecord::Inequality::InequalError do
|
68
|
+
Main.try_like(nil).first
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
should "properly scope based on gte" do
|
73
|
+
time = 2.days.ago
|
74
|
+
num = 3
|
75
|
+
num.times { Main.create(:val => 3) }
|
76
|
+
num.times { Main.create(:val => 1) }
|
77
|
+
|
78
|
+
assert_equal Main.count(:conditions => {:val => gte(2)}), num
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context "an instance" do
|
84
|
+
setup do
|
85
|
+
@main = Main.new
|
86
|
+
end
|
87
|
+
|
88
|
+
should "respond to gte" do
|
89
|
+
assert @main.respond_to?(:gte)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
context "a parent" do
|
95
|
+
setup do
|
96
|
+
@second = Second.new
|
97
|
+
end
|
98
|
+
|
99
|
+
should "see through assocaitions" do
|
100
|
+
assert @second.mains.respond_to?(:gte)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "Object" do
|
105
|
+
should "have gte" do
|
106
|
+
wrapped = gte(5)
|
107
|
+
assert_equal wrapped.operator, '>='
|
108
|
+
assert_equal wrapped, ActiveRecord::Inequality::GreaterThanEqual.new(5)
|
109
|
+
end
|
110
|
+
|
111
|
+
should "have gt" do
|
112
|
+
wrapped = gt(5)
|
113
|
+
assert_equal wrapped.operator, '>'
|
114
|
+
assert_equal wrapped, ActiveRecord::Inequality::GreaterThan.new(5)
|
115
|
+
end
|
116
|
+
|
117
|
+
should "have lte" do
|
118
|
+
wrapped = lte(5)
|
119
|
+
assert_equal wrapped.operator, '<='
|
120
|
+
assert_equal wrapped, ActiveRecord::Inequality::LessThanEqual.new(5)
|
121
|
+
end
|
122
|
+
|
123
|
+
should "have lt" do
|
124
|
+
wrapped = lt(5)
|
125
|
+
assert_equal wrapped.operator, '<'
|
126
|
+
assert_equal wrapped, ActiveRecord::Inequality::LessThan.new(5)
|
127
|
+
end
|
128
|
+
|
129
|
+
should "have ne" do
|
130
|
+
wrapped = ne(5)
|
131
|
+
assert_equal wrapped.operator, '<>'
|
132
|
+
assert_equal wrapped, ActiveRecord::Inequality::NotEqual.new(5)
|
133
|
+
end
|
134
|
+
|
135
|
+
should "have a different operator when calling ne w/ nil" do
|
136
|
+
wrapped = ne(nil)
|
137
|
+
assert_equal wrapped.operator, 'IS NOT'
|
138
|
+
assert_equal wrapped, ActiveRecord::Inequality::NotEqual.new(nil)
|
139
|
+
end
|
140
|
+
|
141
|
+
should "have a different operator when calling ne w/ true" do
|
142
|
+
wrapped = ne(true)
|
143
|
+
assert_equal wrapped.operator, 'IS NOT'
|
144
|
+
assert_equal wrapped, ActiveRecord::Inequality::NotEqual.new(true)
|
145
|
+
end
|
146
|
+
|
147
|
+
should "have a different operator when calling ne w/ false" do
|
148
|
+
wrapped = ne(false)
|
149
|
+
assert_equal wrapped.operator, 'IS NOT'
|
150
|
+
assert_equal wrapped, ActiveRecord::Inequality::NotEqual.new(false)
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
should "have like" do
|
156
|
+
wrapped = like('ryan')
|
157
|
+
assert_equal wrapped.operator, 'LIKE'
|
158
|
+
assert_equal wrapped, ActiveRecord::Inequality::Like.new('ryan')
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
context "expand_range_bind_variables_orig" do
|
164
|
+
should "return a proper array" do
|
165
|
+
range_start = 1
|
166
|
+
range_end = 9
|
167
|
+
|
168
|
+
input = [{:a => 1}, (range_start..range_end), "Yo", {:c => 'd'}, 23, [1,2,3]]
|
169
|
+
res = ActiveRecord::Base.send :expand_range_bind_variables_orig, input
|
170
|
+
|
171
|
+
assert_equal res, [range_start, range_end, "Yo", 23, [1,2,3]]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: inequal_opportunity
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Ryan Angilly
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-18 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Adds mergable, stackable inequality statements to ActiveRecord conditions
|
22
|
+
email: ryan@angilly.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README
|
29
|
+
files:
|
30
|
+
- .gitignore
|
31
|
+
- MIT-LICENSE
|
32
|
+
- README
|
33
|
+
- Rakefile
|
34
|
+
- VERSION.yml
|
35
|
+
- inequal_opportunity.gemspec
|
36
|
+
- init.rb
|
37
|
+
- lib/inequal_opportunity.rb
|
38
|
+
- test/database.example.yml
|
39
|
+
- test/db_setup.rb
|
40
|
+
- test/inequal_opportunity_test.rb
|
41
|
+
- test/test_helper.rb
|
42
|
+
has_rdoc: true
|
43
|
+
homepage: http://github.com/ryana/inequal_opportunity
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options:
|
48
|
+
- --charset=UTF-8
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
version: "0"
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.3.6
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: Adds mergable, stackable inequality statements to ActiveRecord conditions
|
72
|
+
test_files:
|
73
|
+
- test/db_setup.rb
|
74
|
+
- test/inequal_opportunity_test.rb
|
75
|
+
- test/test_helper.rb
|