searchlogic-donotuse 2.3.9
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.
- checksums.yaml +15 -0
- data/CHANGELOG.rdoc +418 -0
- data/LICENSE +20 -0
- data/README.rdoc +299 -0
- data/Rakefile +19 -0
- data/VERSION.yml +5 -0
- data/init.rb +1 -0
- data/lib/searchlogic.rb +40 -0
- data/lib/searchlogic/active_record/consistency.rb +32 -0
- data/lib/searchlogic/active_record/named_scopes.rb +60 -0
- data/lib/searchlogic/core_ext/object.rb +41 -0
- data/lib/searchlogic/core_ext/proc.rb +11 -0
- data/lib/searchlogic/named_scopes/alias_scope.rb +67 -0
- data/lib/searchlogic/named_scopes/association_conditions.rb +102 -0
- data/lib/searchlogic/named_scopes/association_ordering.rb +43 -0
- data/lib/searchlogic/named_scopes/conditions.rb +229 -0
- data/lib/searchlogic/named_scopes/or_conditions.rb +137 -0
- data/lib/searchlogic/named_scopes/ordering.rb +48 -0
- data/lib/searchlogic/rails_helpers.rb +76 -0
- data/lib/searchlogic/search.rb +179 -0
- data/rails/init.rb +1 -0
- data/searchlogic.gemspec +85 -0
- data/spec/core_ext/object_spec.rb +7 -0
- data/spec/core_ext/proc_spec.rb +9 -0
- data/spec/named_scopes/alias_scope_spec.rb +19 -0
- data/spec/named_scopes/association_conditions_spec.rb +141 -0
- data/spec/named_scopes/association_ordering_spec.rb +27 -0
- data/spec/named_scopes/conditions_spec.rb +319 -0
- data/spec/named_scopes/or_conditions_spec.rb +59 -0
- data/spec/named_scopes/ordering_spec.rb +34 -0
- data/spec/search_spec.rb +369 -0
- data/spec/spec_helper.rb +104 -0
- metadata +89 -0
@@ -0,0 +1,137 @@
|
|
1
|
+
module Searchlogic
|
2
|
+
module NamedScopes
|
3
|
+
# Handles dynamically creating named scopes for 'OR' conditions. Please see the README for a more
|
4
|
+
# detailed explanation.
|
5
|
+
module OrConditions
|
6
|
+
class NoConditionSpecifiedError < StandardError; end
|
7
|
+
class UnknownConditionError < StandardError; end
|
8
|
+
|
9
|
+
def condition?(name) # :nodoc:
|
10
|
+
super || or_condition?(name)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def or_condition?(name)
|
15
|
+
!or_conditions(name).nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(name, *args, &block)
|
19
|
+
if conditions = or_conditions(name)
|
20
|
+
create_or_condition(conditions, args)
|
21
|
+
(class << self; self; end).class_eval { alias_method name, conditions.join("_or_") } if !respond_to?(name)
|
22
|
+
send(name, *args)
|
23
|
+
else
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def or_conditions(name)
|
29
|
+
# First determine if we should even work on the name, we want to be as quick as possible
|
30
|
+
# with this.
|
31
|
+
if (parts = split_or_condition(name)).size > 1
|
32
|
+
conditions = interpolate_or_conditions(parts)
|
33
|
+
if conditions.any?
|
34
|
+
conditions
|
35
|
+
else
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def split_or_condition(name)
|
42
|
+
parts = name.to_s.split("_or_")
|
43
|
+
new_parts = []
|
44
|
+
parts.each do |part|
|
45
|
+
if part =~ /^equal_to(_any|_all)?$/
|
46
|
+
new_parts << new_parts.pop + "_or_equal_to"
|
47
|
+
else
|
48
|
+
new_parts << part
|
49
|
+
end
|
50
|
+
end
|
51
|
+
new_parts
|
52
|
+
end
|
53
|
+
|
54
|
+
# The purpose of this method is to convert the method name parts into actual condition names.
|
55
|
+
#
|
56
|
+
# Example:
|
57
|
+
#
|
58
|
+
# ["first_name", "last_name_like"]
|
59
|
+
# => ["first_name_like", "last_name_like"]
|
60
|
+
#
|
61
|
+
# ["id_gt", "first_name_begins_with", "last_name", "middle_name_like"]
|
62
|
+
# => ["id_gt", "first_name_begins_with", "last_name_like", "middle_name_like"]
|
63
|
+
#
|
64
|
+
# Basically if a column is specified without a condition the next condition in the list
|
65
|
+
# is what will be used. Once we are able to get a consistent list of conditions we can easily
|
66
|
+
# create a scope for it.
|
67
|
+
def interpolate_or_conditions(parts)
|
68
|
+
conditions = []
|
69
|
+
last_condition = nil
|
70
|
+
|
71
|
+
parts.reverse.each do |part|
|
72
|
+
if details = condition_details(part)
|
73
|
+
# We are a searchlogic defined scope
|
74
|
+
conditions << "#{details[:column]}_#{details[:condition]}"
|
75
|
+
last_condition = details[:condition]
|
76
|
+
elsif association_details = association_condition_details(part, last_condition)
|
77
|
+
path = full_association_path(part, last_condition, association_details[:association])
|
78
|
+
conditions << "#{path[:path].join("_").to_sym}_#{path[:column]}_#{path[:condition]}"
|
79
|
+
last_condition = path[:condition] || nil
|
80
|
+
elsif local_condition?(part)
|
81
|
+
# We are a custom scope
|
82
|
+
conditions << part
|
83
|
+
elsif column_names.include?(part)
|
84
|
+
# we are a column, use the last condition
|
85
|
+
if last_condition.nil?
|
86
|
+
raise NoConditionSpecifiedError.new("The '#{part}' column doesn't know which condition to use, if you use an exact column " +
|
87
|
+
"name you need to specify a condition sometime after (ex: id_or_created_at_lt), where id would use the 'lt' condition.")
|
88
|
+
end
|
89
|
+
|
90
|
+
conditions << "#{part}_#{last_condition}"
|
91
|
+
else
|
92
|
+
raise UnknownConditionError.new("The condition '#{part}' is not a valid condition, we could not find any scopes that match this.")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
conditions.reverse
|
97
|
+
end
|
98
|
+
|
99
|
+
def full_association_path(part, last_condition, given_assoc)
|
100
|
+
path = [given_assoc.to_sym]
|
101
|
+
part.sub!(/^#{given_assoc}_/, "")
|
102
|
+
klass = self
|
103
|
+
while klass = klass.send(:reflect_on_association, given_assoc.to_sym)
|
104
|
+
klass = klass.klass
|
105
|
+
if details = klass.send(:association_condition_details, part, last_condition)
|
106
|
+
path << details[:association]
|
107
|
+
part = details[:condition]
|
108
|
+
given_assoc = details[:association]
|
109
|
+
elsif details = klass.send(:condition_details, part, nil)
|
110
|
+
return { :path => path, :column => details[:column], :condition => details[:condition] }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
{ :path => path, :column => part, :condition => last_condition }
|
114
|
+
end
|
115
|
+
|
116
|
+
def create_or_condition(scopes, args)
|
117
|
+
named_scope scopes.join("_or_"), lambda { |*args|
|
118
|
+
merge_scopes_with_or(scopes.collect { |scope| [scope, *args] })
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
def merge_scopes_with_or(scopes)
|
123
|
+
scopes_options = scopes.collect { |scope, *args| send(scope, *args).proxy_options }
|
124
|
+
conditions = scopes_options.reject { |o| o[:conditions].nil? }.collect { |o| sanitize_sql(o[:conditions]) }
|
125
|
+
|
126
|
+
scope = scopes.inject(scoped({})) do |scope, info|
|
127
|
+
scope_name, *args = info
|
128
|
+
scope.send(scope_name, *args)
|
129
|
+
end
|
130
|
+
|
131
|
+
options = scope.scope(:find)
|
132
|
+
options.delete(:readonly) unless scope.proxy_options.key?(:readonly)
|
133
|
+
options.merge(:conditions => "(" + conditions.join(") OR (") + ")")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Searchlogic
|
2
|
+
module NamedScopes
|
3
|
+
# Handles dynamically creating named scopes for ordering by columns. Example:
|
4
|
+
#
|
5
|
+
# User.ascend_by_id
|
6
|
+
# User.descend_by_username
|
7
|
+
#
|
8
|
+
# See the README for a more detailed explanation.
|
9
|
+
module Ordering
|
10
|
+
def condition?(name) # :nodoc:
|
11
|
+
super || ordering_condition?(name)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def ordering_condition?(name) # :nodoc:
|
16
|
+
!ordering_condition_details(name).nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(name, *args, &block)
|
20
|
+
if name == :order
|
21
|
+
named_scope name, lambda { |scope_name|
|
22
|
+
return {} if !condition?(scope_name)
|
23
|
+
send(scope_name).proxy_options
|
24
|
+
}
|
25
|
+
send(name, *args)
|
26
|
+
elsif details = ordering_condition_details(name)
|
27
|
+
create_ordering_conditions(details[:column])
|
28
|
+
send(name, *args)
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def ordering_condition_details(name)
|
35
|
+
if name.to_s =~ /^(ascend|descend)_by_(#{column_names.join("|")})$/
|
36
|
+
{:order_as => $1, :column => $2}
|
37
|
+
elsif name.to_s =~ /^order$/
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_ordering_conditions(column)
|
43
|
+
named_scope("ascend_by_#{column}".to_sym, {:order => "#{table_name}.#{column} ASC"})
|
44
|
+
named_scope("descend_by_#{column}".to_sym, {:order => "#{table_name}.#{column} DESC"})
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Searchlogic
|
2
|
+
module RailsHelpers
|
3
|
+
# Creates a link that alternates between acending and descending. It basically
|
4
|
+
# alternates between calling 2 named scopes: "ascend_by_*" and "descend_by_*"
|
5
|
+
#
|
6
|
+
# By default Searchlogic gives you these named scopes for all of your columns, but
|
7
|
+
# if you wanted to create your own, it will work with those too.
|
8
|
+
#
|
9
|
+
# Examples:
|
10
|
+
#
|
11
|
+
# order @search, :by => :username
|
12
|
+
# order @search, :by => :created_at, :as => "Created"
|
13
|
+
#
|
14
|
+
# This helper accepts the following options:
|
15
|
+
#
|
16
|
+
# * <tt>:by</tt> - the name of the named scope. This helper will prepend this value with "ascend_by_" and "descend_by_"
|
17
|
+
# * <tt>:as</tt> - the text used in the link, defaults to whatever is passed to :by
|
18
|
+
# * <tt>:ascend_scope</tt> - what scope to call for ascending the data, defaults to "ascend_by_:by"
|
19
|
+
# * <tt>:descend_scope</tt> - what scope to call for descending the data, defaults to "descend_by_:by"
|
20
|
+
# * <tt>:params</tt> - hash with additional params which will be added to generated url
|
21
|
+
# * <tt>:params_scope</tt> - the name of the params key to scope the order condition by, defaults to :search
|
22
|
+
def order(search, options = {}, html_options = {})
|
23
|
+
options[:params_scope] ||= :search
|
24
|
+
if !options[:as]
|
25
|
+
id = options[:by].to_s.downcase == "id"
|
26
|
+
options[:as] = id ? options[:by].to_s.upcase : options[:by].to_s.humanize
|
27
|
+
end
|
28
|
+
options[:ascend_scope] ||= "ascend_by_#{options[:by]}"
|
29
|
+
options[:descend_scope] ||= "descend_by_#{options[:by]}"
|
30
|
+
ascending = search.order.to_s == options[:ascend_scope]
|
31
|
+
new_scope = ascending ? options[:descend_scope] : options[:ascend_scope]
|
32
|
+
selected = [options[:ascend_scope], options[:descend_scope]].include?(search.order.to_s)
|
33
|
+
if selected
|
34
|
+
css_classes = html_options[:class] ? html_options[:class].split(" ") : []
|
35
|
+
if ascending
|
36
|
+
options[:as] = "▲ #{options[:as]}"
|
37
|
+
css_classes << "ascending"
|
38
|
+
else
|
39
|
+
options[:as] = "▼ #{options[:as]}"
|
40
|
+
css_classes << "descending"
|
41
|
+
end
|
42
|
+
html_options[:class] = css_classes.join(" ")
|
43
|
+
end
|
44
|
+
url_options = {
|
45
|
+
options[:params_scope] => search.conditions.merge( { :order => new_scope } )
|
46
|
+
}.deep_merge(options[:params] || {})
|
47
|
+
link_to options[:as], url_for(url_options), html_options
|
48
|
+
end
|
49
|
+
|
50
|
+
# Automatically makes the form method :get if a Searchlogic::Search and sets
|
51
|
+
# the params scope to :search
|
52
|
+
def form_for(*args, &block)
|
53
|
+
if search_obj = args.find { |arg| arg.is_a?(Searchlogic::Search) }
|
54
|
+
options = args.extract_options!
|
55
|
+
options[:html] ||= {}
|
56
|
+
options[:html][:method] ||= :get
|
57
|
+
options[:url] ||= url_for
|
58
|
+
args.unshift(:search) if args.first == search_obj
|
59
|
+
args << options
|
60
|
+
end
|
61
|
+
super
|
62
|
+
end
|
63
|
+
|
64
|
+
# Automatically adds an "order" hidden field in your form to preserve how the data
|
65
|
+
# is being ordered.
|
66
|
+
def fields_for(*args, &block)
|
67
|
+
if search_obj = args.find { |arg| arg.is_a?(Searchlogic::Search) }
|
68
|
+
args.unshift(:search) if args.first == search_obj
|
69
|
+
concat(content_tag("div", hidden_field_tag("#{args.first}[order]", search_obj.order)) + "\n")
|
70
|
+
super
|
71
|
+
else
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module Searchlogic
|
2
|
+
# A class that acts like a model, creates attr_accessors for named_scopes, and then
|
3
|
+
# chains together everything when an "action" method is called. It basically makes
|
4
|
+
# implementing search forms in your application effortless:
|
5
|
+
#
|
6
|
+
# search = User.search
|
7
|
+
# search.username_like = "bjohnson"
|
8
|
+
# search.all
|
9
|
+
#
|
10
|
+
# Is equivalent to:
|
11
|
+
#
|
12
|
+
# User.search(:username_like => "bjohnson").all
|
13
|
+
#
|
14
|
+
# Is equivalent to:
|
15
|
+
#
|
16
|
+
# User.username_like("bjohnson").all
|
17
|
+
class Search
|
18
|
+
# Responsible for adding a "search" method into your models.
|
19
|
+
module Implementation
|
20
|
+
# Additional method, gets aliased as "search" if that method
|
21
|
+
# is available. A lot of other libraries like to use "search"
|
22
|
+
# as well, so if you have a conflict like this, you can use
|
23
|
+
# this method directly.
|
24
|
+
def searchlogic(conditions = {})
|
25
|
+
Search.new(self, scope(:find), conditions)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Is an invalid condition is used this error will be raised. Ex:
|
30
|
+
#
|
31
|
+
# User.search(:unkown => true)
|
32
|
+
#
|
33
|
+
# Where unknown is not a valid named scope for the User model.
|
34
|
+
class UnknownConditionError < StandardError
|
35
|
+
def initialize(condition)
|
36
|
+
msg = "The #{condition} is not a valid condition. You may only use conditions that map to a named scope"
|
37
|
+
super(msg)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_accessor :klass, :current_scope, :conditions
|
42
|
+
undef :id if respond_to?(:id)
|
43
|
+
|
44
|
+
# Creates a new search object for the given class. Ex:
|
45
|
+
#
|
46
|
+
# Searchlogic::Search.new(User, {}, {:username_like => "bjohnson"})
|
47
|
+
def initialize(klass, current_scope, conditions = {})
|
48
|
+
self.klass = klass
|
49
|
+
self.current_scope = current_scope
|
50
|
+
self.conditions = conditions if conditions.is_a?(Hash)
|
51
|
+
end
|
52
|
+
|
53
|
+
def clone
|
54
|
+
self.class.new(klass, current_scope && current_scope.clone, conditions.clone)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns a hash of the current conditions set.
|
58
|
+
def conditions
|
59
|
+
@conditions ||= {}
|
60
|
+
end
|
61
|
+
|
62
|
+
# Accepts a hash of conditions.
|
63
|
+
def conditions=(values)
|
64
|
+
values.each do |condition, value|
|
65
|
+
value.delete_if { |v| ignore_value?(v) } if value.is_a?(Array)
|
66
|
+
next if ignore_value?(value)
|
67
|
+
send("#{condition}=", value)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Delete a condition from the search. Since conditions map to named scopes,
|
72
|
+
# if a named scope accepts a parameter there is no way to actually delete
|
73
|
+
# the scope if you do not want it anymore. A nil value might be meaningful
|
74
|
+
# to that scope.
|
75
|
+
def delete(*names)
|
76
|
+
names.each { |name| @conditions.delete(name.to_sym) }
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
def method_missing(name, *args, &block)
|
82
|
+
condition_name = condition_name(name)
|
83
|
+
scope_name = scope_name(condition_name)
|
84
|
+
|
85
|
+
if setter?(name)
|
86
|
+
if scope?(scope_name)
|
87
|
+
conditions[condition_name] = type_cast(args.first, cast_type(scope_name))
|
88
|
+
else
|
89
|
+
raise UnknownConditionError.new(condition_name)
|
90
|
+
end
|
91
|
+
elsif scope?(scope_name)
|
92
|
+
if args.size > 0
|
93
|
+
send("#{condition_name}=", *args)
|
94
|
+
self
|
95
|
+
else
|
96
|
+
conditions[condition_name]
|
97
|
+
end
|
98
|
+
else
|
99
|
+
scope = conditions.inject(klass.scoped(current_scope) || {}) do |scope, condition|
|
100
|
+
scope_name, value = condition
|
101
|
+
scope_name = normalize_scope_name(scope_name)
|
102
|
+
klass.send(scope_name, value) if !klass.respond_to?(scope_name)
|
103
|
+
arity = klass.named_scope_arity(scope_name)
|
104
|
+
|
105
|
+
if !arity || arity == 0
|
106
|
+
if value == true
|
107
|
+
scope.send(scope_name)
|
108
|
+
else
|
109
|
+
scope
|
110
|
+
end
|
111
|
+
else
|
112
|
+
if value.is_a?(Array)
|
113
|
+
scope.send(scope_name, *value)
|
114
|
+
else
|
115
|
+
scope.send(scope_name, value)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
scope.send(name, *args, &block)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def normalize_scope_name(scope_name)
|
124
|
+
case
|
125
|
+
when klass.scopes.key?(scope_name.to_sym) then scope_name.to_sym
|
126
|
+
when klass.column_names.include?(scope_name.to_s) then "#{scope_name}_equals".to_sym
|
127
|
+
else scope_name.to_sym
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def setter?(name)
|
132
|
+
!(name.to_s =~ /=$/).nil?
|
133
|
+
end
|
134
|
+
|
135
|
+
def condition_name(name)
|
136
|
+
condition = name.to_s.match(/(\w+)=?$/)
|
137
|
+
condition ? condition[1].to_sym : nil
|
138
|
+
end
|
139
|
+
|
140
|
+
def scope_name(condition_name)
|
141
|
+
condition_name && normalize_scope_name(condition_name)
|
142
|
+
end
|
143
|
+
|
144
|
+
def scope?(scope_name)
|
145
|
+
klass.scopes.key?(scope_name) || klass.condition?(scope_name)
|
146
|
+
end
|
147
|
+
|
148
|
+
def cast_type(name)
|
149
|
+
klass.send(name, nil) if !klass.respond_to?(name) # We need to set up the named scope if it doesn't exist, so we can get a value for named_scope_options
|
150
|
+
named_scope_options = klass.named_scope_options(name)
|
151
|
+
arity = klass.named_scope_arity(name)
|
152
|
+
if !arity || arity == 0
|
153
|
+
:boolean
|
154
|
+
else
|
155
|
+
named_scope_options.respond_to?(:searchlogic_arg_type) ? named_scope_options.searchlogic_arg_type : :string
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def type_cast(value, type)
|
160
|
+
case value
|
161
|
+
when Array
|
162
|
+
value.collect { |v| type_cast(v, type) }
|
163
|
+
when Range
|
164
|
+
Range.new(type_cast(value.first, type), type_cast(value.last, type))
|
165
|
+
else
|
166
|
+
# Let's leverage ActiveRecord's type casting, so that casting is consistent
|
167
|
+
# with the other models.
|
168
|
+
column_for_type_cast = ::ActiveRecord::ConnectionAdapters::Column.new("", nil)
|
169
|
+
column_for_type_cast.instance_variable_set(:@type, type)
|
170
|
+
value = column_for_type_cast.type_cast(value)
|
171
|
+
Time.zone && value.is_a?(Time) ? value.in_time_zone : value
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def ignore_value?(value)
|
176
|
+
(value.is_a?(String) && value.blank?) || (value.is_a?(Array) && value.empty?)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "searchlogic"
|
data/searchlogic.gemspec
ADDED
@@ -0,0 +1,85 @@
|
|
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{searchlogic-donotuse}
|
8
|
+
s.version = "2.3.9"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ben Johnson of Binary Logic"]
|
12
|
+
s.date = %q{2009-11-27}
|
13
|
+
s.description = %q{Searchlogic makes using ActiveRecord named scopes easier and less repetitive.}
|
14
|
+
s.email = %q{bjohnson@binarylogic.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"CHANGELOG.rdoc",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION.yml",
|
26
|
+
"init.rb",
|
27
|
+
"lib/searchlogic.rb",
|
28
|
+
"lib/searchlogic/active_record/consistency.rb",
|
29
|
+
"lib/searchlogic/active_record/named_scopes.rb",
|
30
|
+
"lib/searchlogic/core_ext/object.rb",
|
31
|
+
"lib/searchlogic/core_ext/proc.rb",
|
32
|
+
"lib/searchlogic/named_scopes/alias_scope.rb",
|
33
|
+
"lib/searchlogic/named_scopes/association_conditions.rb",
|
34
|
+
"lib/searchlogic/named_scopes/association_ordering.rb",
|
35
|
+
"lib/searchlogic/named_scopes/conditions.rb",
|
36
|
+
"lib/searchlogic/named_scopes/or_conditions.rb",
|
37
|
+
"lib/searchlogic/named_scopes/ordering.rb",
|
38
|
+
"lib/searchlogic/rails_helpers.rb",
|
39
|
+
"lib/searchlogic/search.rb",
|
40
|
+
"rails/init.rb",
|
41
|
+
"searchlogic.gemspec",
|
42
|
+
"spec/core_ext/object_spec.rb",
|
43
|
+
"spec/core_ext/proc_spec.rb",
|
44
|
+
"spec/named_scopes/alias_scope_spec.rb",
|
45
|
+
"spec/named_scopes/association_conditions_spec.rb",
|
46
|
+
"spec/named_scopes/association_ordering_spec.rb",
|
47
|
+
"spec/named_scopes/conditions_spec.rb",
|
48
|
+
"spec/named_scopes/or_conditions_spec.rb",
|
49
|
+
"spec/named_scopes/ordering_spec.rb",
|
50
|
+
"spec/search_spec.rb",
|
51
|
+
"spec/spec_helper.rb"
|
52
|
+
]
|
53
|
+
s.homepage = %q{http://github.com/binarylogic/searchlogic}
|
54
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
55
|
+
s.require_paths = ["lib"]
|
56
|
+
s.rubyforge_project = %q{searchlogic-donotuse}
|
57
|
+
s.rubygems_version = %q{1.3.5}
|
58
|
+
s.summary = %q{Searchlogic makes using ActiveRecord named scopes easier and less repetitive.}
|
59
|
+
s.test_files = [
|
60
|
+
"spec/core_ext/object_spec.rb",
|
61
|
+
"spec/core_ext/proc_spec.rb",
|
62
|
+
"spec/named_scopes/alias_scope_spec.rb",
|
63
|
+
"spec/named_scopes/association_conditions_spec.rb",
|
64
|
+
"spec/named_scopes/association_ordering_spec.rb",
|
65
|
+
"spec/named_scopes/conditions_spec.rb",
|
66
|
+
"spec/named_scopes/or_conditions_spec.rb",
|
67
|
+
"spec/named_scopes/ordering_spec.rb",
|
68
|
+
"spec/search_spec.rb",
|
69
|
+
"spec/spec_helper.rb"
|
70
|
+
]
|
71
|
+
|
72
|
+
if s.respond_to? :specification_version then
|
73
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
74
|
+
s.specification_version = 3
|
75
|
+
|
76
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
77
|
+
s.add_runtime_dependency(%q<activerecord>, ["== 2.3.9"])
|
78
|
+
else
|
79
|
+
s.add_dependency(%q<activerecord>, ["== 2.3.9"])
|
80
|
+
end
|
81
|
+
else
|
82
|
+
s.add_dependency(%q<activerecord>, ["== 2.3.9"])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|