ransack 0.3.0 → 0.4.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.
@@ -1,18 +1,17 @@
1
+ require 'ransack/adapters/active_record/base'
2
+ ActiveRecord::Base.extend Ransack::Adapters::ActiveRecord::Base
3
+
1
4
  case ActiveRecord::VERSION::STRING
2
5
  when /^3\.0\./
3
- require 'ransack/adapters/active_record/3.0/base'
4
6
  require 'ransack/adapters/active_record/3.0/join_dependency'
5
7
  require 'ransack/adapters/active_record/3.0/join_association'
6
8
  require 'ransack/adapters/active_record/3.0/context'
7
9
 
8
- ActiveRecord::Base.extend Ransack::Adapters::ActiveRecord::Base
9
10
  ActiveRecord::Associations::ClassMethods::JoinDependency.send :include, Ransack::Adapters::ActiveRecord::JoinDependency
10
11
  else
11
- require 'ransack/adapters/active_record/base'
12
12
  require 'ransack/adapters/active_record/join_dependency'
13
13
  require 'ransack/adapters/active_record/join_association'
14
14
  require 'ransack/adapters/active_record/context'
15
15
 
16
- ActiveRecord::Base.extend Ransack::Adapters::ActiveRecord::Base
17
16
  ActiveRecord::Associations::JoinDependency.send :include, Ransack::Adapters::ActiveRecord::JoinDependency
18
17
  end
@@ -20,4 +20,147 @@ class ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase
20
20
  :engine => active_record.arel_engine,
21
21
  :columns => active_record.columns)
22
22
  end
23
+ end
24
+
25
+ module Arel
26
+
27
+ class Table
28
+ alias :table_name :name
29
+
30
+ def [] name
31
+ ::Arel::Attribute.new self, name.to_sym
32
+ end
33
+ end
34
+
35
+ module Nodes
36
+ class Node
37
+ def not
38
+ Nodes::Not.new self
39
+ end
40
+ end
41
+
42
+ remove_const :And
43
+ class And < Arel::Nodes::Node
44
+ attr_reader :children
45
+
46
+ def initialize children, right = nil
47
+ unless Array === children
48
+ children = [children, right]
49
+ end
50
+ @children = children
51
+ end
52
+
53
+ def left
54
+ children.first
55
+ end
56
+
57
+ def right
58
+ children[1]
59
+ end
60
+ end
61
+
62
+ class NamedFunction < Arel::Nodes::Function
63
+ attr_accessor :name, :distinct
64
+
65
+ include Arel::Predications
66
+
67
+ def initialize name, expr, aliaz = nil
68
+ super(expr, aliaz)
69
+ @name = name
70
+ @distinct = false
71
+ end
72
+ end
73
+
74
+ class InfixOperation < Binary
75
+ include Arel::Expressions
76
+ include Arel::Predications
77
+
78
+ attr_reader :operator
79
+
80
+ def initialize operator, left, right
81
+ super(left, right)
82
+ @operator = operator
83
+ end
84
+ end
85
+
86
+ class Multiplication < InfixOperation
87
+ def initialize left, right
88
+ super(:*, left, right)
89
+ end
90
+ end
91
+
92
+ class Division < InfixOperation
93
+ def initialize left, right
94
+ super(:/, left, right)
95
+ end
96
+ end
97
+
98
+ class Addition < InfixOperation
99
+ def initialize left, right
100
+ super(:+, left, right)
101
+ end
102
+ end
103
+
104
+ class Subtraction < InfixOperation
105
+ def initialize left, right
106
+ super(:-, left, right)
107
+ end
108
+ end
109
+ end
110
+
111
+ module Visitors
112
+ class ToSql
113
+ def column_for attr
114
+ name = attr.name.to_s
115
+ table = attr.relation.table_name
116
+
117
+ column_cache[table][name]
118
+ end
119
+
120
+ def column_cache
121
+ @column_cache ||= Hash.new do |hash, key|
122
+ hash[key] = Hash[
123
+ @engine.connection.columns(key, "#{key} Columns").map do |c|
124
+ [c.name, c]
125
+ end
126
+ ]
127
+ end
128
+ end
129
+
130
+ def visit_Arel_Nodes_InfixOperation o
131
+ "#{visit o.left} #{o.operator} #{visit o.right}"
132
+ end
133
+
134
+ def visit_Arel_Nodes_NamedFunction o
135
+ "#{o.name}(#{o.distinct ? 'DISTINCT ' : ''}#{o.expressions.map { |x|
136
+ visit x
137
+ }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
138
+ end
139
+
140
+ def visit_Arel_Nodes_And o
141
+ o.children.map { |x| visit x }.join ' AND '
142
+ end
143
+
144
+ def visit_Arel_Nodes_Not o
145
+ "NOT (#{visit o.expr})"
146
+ end
147
+
148
+ def visit_Arel_Nodes_Values o
149
+ "VALUES (#{o.expressions.zip(o.columns).map { |value, attr|
150
+ if Nodes::SqlLiteral === value
151
+ visit_Arel_Nodes_SqlLiteral value
152
+ else
153
+ quote(value, attr && column_for(attr))
154
+ end
155
+ }.join ', '})"
156
+ end
157
+ end
158
+ end
159
+
160
+ module Predications
161
+ def as other
162
+ Nodes::As.new self, Nodes::SqlLiteral.new(other)
163
+ end
164
+ end
165
+
23
166
  end
@@ -19,12 +19,11 @@ module Ransack
19
19
  Ransacker.new(self, name, opts, &block)
20
20
  end
21
21
 
22
- # TODO: Let's actually do some authorization. Whitelist-only.
23
- def ransackable_attributes(auth_object)
22
+ def ransackable_attributes(auth_object = nil)
24
23
  column_names + _ransackers.keys
25
24
  end
26
25
 
27
- def ransackable_associations(auth_object)
26
+ def ransackable_associations(auth_object = nil)
28
27
  reflect_on_all_associations.map {|a| a.name.to_s}
29
28
  end
30
29
 
@@ -7,7 +7,7 @@ module Ransack
7
7
  mattr_accessor :predicates
8
8
  self.predicates = {}
9
9
 
10
- def self.predicate_keys
10
+ def predicate_keys
11
11
  predicates.keys.sort {|a,b| b.length <=> a.length}
12
12
  end
13
13
 
@@ -77,12 +77,8 @@ module Ransack
77
77
  search_fields(:c, args, block)
78
78
  end
79
79
 
80
- def and_fields(*args, &block)
81
- search_fields(:n, args, block)
82
- end
83
-
84
- def or_fields(*args, &block)
85
- search_fields(:o, args, block)
80
+ def grouping_fields(*args, &block)
81
+ search_fields(:g, args, block)
86
82
  end
87
83
 
88
84
  def attribute_fields(*args, &block)
@@ -114,15 +110,27 @@ module Ransack
114
110
  end
115
111
 
116
112
  def predicate_select(options = {}, html_options = {})
113
+ options[:compounds] = true if options[:compounds].nil?
114
+ keys = options[:compounds] ? Ransack.predicate_keys : Ransack.predicate_keys.reject {|k| k.match(/_(any|all)$/)}
115
+ if only = options[:only]
116
+ if only.respond_to? :call
117
+ keys = keys.select {|k| only.call(k)}
118
+ else
119
+ only = Array.wrap(only).map(&:to_s)
120
+ keys = keys.select {|k| only.include? k.sub(/_(any|all)$/, '')}
121
+ end
122
+ end
123
+
117
124
  @template.collection_select(
118
- @object_name, :p, Predicate.collection, :first, :last,
125
+ @object_name, :p, keys.map {|k| [k, Translate.predicate(k)]}, :first, :last,
119
126
  objectify_options(options), @default_options.merge(html_options)
120
127
  )
121
128
  end
122
129
 
123
130
  def combinator_select(options = {}, html_options = {})
131
+ choices = Nodes::Condition === object ? [:or, :and] : [:and, :or]
124
132
  @template.collection_select(
125
- @object_name, :m, [['or', Translate.word(:or)], ['and', Translate.word(:and)]], :first, :last,
133
+ @object_name, :m, choices.map {|o| [o.to_s, Translate.word(o)]}, :first, :last,
126
134
  objectify_options(options), @default_options.merge(html_options)
127
135
  )
128
136
  end
@@ -4,5 +4,4 @@ require 'ransack/nodes/attribute'
4
4
  require 'ransack/nodes/value'
5
5
  require 'ransack/nodes/condition'
6
6
  require 'ransack/nodes/sort'
7
- require 'ransack/nodes/and'
8
- require 'ransack/nodes/or'
7
+ require 'ransack/nodes/grouping'
@@ -28,7 +28,7 @@ module Ransack
28
28
 
29
29
  def extract_attributes_and_predicate(key)
30
30
  str = key.dup
31
- name = Ransack::Configuration.predicate_keys.detect {|p| str.sub!(/_#{p}$/, '')}
31
+ name = Ransack.predicate_keys.detect {|p| str.sub!(/_#{p}$/, '')}
32
32
  predicate = Predicate.named(name)
33
33
  raise ArgumentError, "No valid predicate for #{key}" unless predicate
34
34
  attributes = str.split(/_and_|_or_/)
@@ -2,11 +2,20 @@ module Ransack
2
2
  module Nodes
3
3
  class Grouping < Node
4
4
  attr_reader :conditions
5
+ attr_accessor :combinator
6
+ alias :m :combinator
7
+ alias :m= :combinator=
8
+
5
9
  i18n_word :condition, :and, :or
6
10
  i18n_alias :c => :condition, :n => :and, :o => :or
7
11
 
8
12
  delegate :each, :to => :values
9
13
 
14
+ def initialize(context, combinator = nil)
15
+ super(context)
16
+ self.combinator = combinator.to_s if combinator
17
+ end
18
+
10
19
  def persisted?
11
20
  false
12
21
  end
@@ -52,7 +61,7 @@ module Ransack
52
61
  end
53
62
 
54
63
  def values
55
- conditions + ors + ands
64
+ conditions + groupings
56
65
  end
57
66
 
58
67
  def respond_to?(method_id)
@@ -79,51 +88,28 @@ module Ransack
79
88
  condition
80
89
  end
81
90
 
82
- def ands
83
- @ands ||= []
91
+ def groupings
92
+ @groupings ||= []
84
93
  end
85
- alias :n :ands
94
+ alias :g :groupings
86
95
 
87
- def ands=(ands)
88
- case ands
96
+ def groupings=(groupings)
97
+ case groupings
89
98
  when Array
90
- ands.each do |attrs|
91
- and_object = And.new(@context).build(attrs)
92
- self.ands << and_object if and_object.values.any?
99
+ groupings.each do |attrs|
100
+ grouping_object = new_grouping(attrs)
101
+ self.groupings << grouping_object if grouping_object.values.any?
93
102
  end
94
103
  when Hash
95
- ands.each do |index, attrs|
96
- and_object = And.new(@context).build(attrs)
97
- self.ands << and_object if and_object.values.any?
104
+ groupings.each do |index, attrs|
105
+ grouping_object = new_grouping(attrs)
106
+ self.groupings << grouping_object if grouping_object.values.any?
98
107
  end
99
108
  else
100
- raise ArgumentError, "Invalid argument (#{ands.class}) supplied to ands="
109
+ raise ArgumentError, "Invalid argument (#{groupings.class}) supplied to groupings="
101
110
  end
102
111
  end
103
- alias :n= :ands=
104
-
105
- def ors
106
- @ors ||= []
107
- end
108
- alias :o :ors
109
-
110
- def ors=(ors)
111
- case ors
112
- when Array
113
- ors.each do |attrs|
114
- or_object = Or.new(@context).build(attrs)
115
- self.ors << or_object if or_object.values.any?
116
- end
117
- when Hash
118
- ors.each do |index, attrs|
119
- or_object = Or.new(@context).build(attrs)
120
- self.ors << or_object if or_object.values.any?
121
- end
122
- else
123
- raise ArgumentError, "Invalid argument (#{ors.class}) supplied to ors="
124
- end
125
- end
126
- alias :o= :ors=
112
+ alias :g= :groupings=
127
113
 
128
114
  def method_missing(method_id, *args)
129
115
  method_name = method_id.to_s
@@ -138,39 +124,28 @@ module Ransack
138
124
  def attribute_method?(name)
139
125
  name = strip_predicate_and_index(name)
140
126
  case name
141
- when /^(n|o|c|ands|ors|conditions)=?$/
127
+ when /^(g|c|m|groupings|conditions|combinator)=?$/
142
128
  true
143
129
  else
144
130
  name.split(/_and_|_or_/).select {|n| !@context.attribute_method?(n)}.empty?
145
131
  end
146
132
  end
147
133
 
148
- def build_and(params = {})
149
- params ||= {}
150
- new_and(params).tap do |new_and|
151
- self.ands << new_and
152
- end
153
- end
154
-
155
- def new_and(params = {})
156
- And.new(@context).build(params)
157
- end
158
-
159
- def build_or(params = {})
134
+ def build_grouping(params = {})
160
135
  params ||= {}
161
- new_or(params).tap do |new_or|
162
- self.ors << new_or
136
+ new_grouping(params).tap do |new_grouping|
137
+ self.groupings << new_grouping
163
138
  end
164
139
  end
165
140
 
166
- def new_or(params = {})
167
- Or.new(@context).build(params)
141
+ def new_grouping(params = {})
142
+ Grouping.new(@context).build(params)
168
143
  end
169
144
 
170
145
  def build(params)
171
146
  params.with_indifferent_access.each do |key, value|
172
147
  case key
173
- when /^(n|o|c)$/
148
+ when /^(g|c|m)$/
174
149
  self.send("#{key}=", value)
175
150
  else
176
151
  write_attribute(key.to_s, value)
@@ -198,7 +173,7 @@ module Ransack
198
173
 
199
174
  def strip_predicate_and_index(str)
200
175
  string = str.split(/\(/).first
201
- Ransack::Configuration.predicate_keys.detect {|p| string.sub!(/_#{p}$/, '')}
176
+ Ransack.predicate_keys.detect {|p| string.sub!(/_#{p}$/, '')}
202
177
  string
203
178
  end
204
179
 
@@ -4,15 +4,11 @@ module Ransack
4
4
 
5
5
  class << self
6
6
  def named(name)
7
- Configuration.predicates[name.to_s]
7
+ Ransack.predicates[name.to_s]
8
8
  end
9
9
 
10
10
  def for_attribute_name(attribute_name)
11
- self.named(Configuration.predicate_keys.detect {|p| attribute_name.to_s.match(/_#{p}$/)})
12
- end
13
-
14
- def collection
15
- Configuration.predicates.map {|k, v| [k, Translate.predicate(k)]}
11
+ self.named(Ransack.predicate_keys.detect {|p| attribute_name.to_s.match(/_#{p}$/)})
16
12
  end
17
13
  end
18
14
 
@@ -9,15 +9,15 @@ module Ransack
9
9
  attr_reader :base, :context
10
10
 
11
11
  delegate :object, :klass, :to => :context
12
- delegate :new_and, :new_or, :new_condition,
13
- :build_and, :build_or, :build_condition,
12
+ delegate :new_grouping, :new_condition,
13
+ :build_grouping, :build_condition,
14
14
  :translate, :to => :base
15
15
 
16
16
  def initialize(object, params = {}, options = {})
17
17
  params ||= {}
18
18
  @context = Context.for(object)
19
19
  @context.auth_object = options[:auth_object]
20
- @base = Nodes::And.new(@context)
20
+ @base = Nodes::Grouping.new(@context, 'and')
21
21
  build(params.with_indifferent_access)
22
22
  end
23
23
 
@@ -18,7 +18,7 @@ module Ransack
18
18
  original_name = key.to_s
19
19
  base_class = context.klass
20
20
  base_ancestors = base_class.ancestors.select { |x| x.respond_to?(:model_name) }
21
- predicate = Ransack::Configuration.predicate_keys.detect {|p| original_name.match(/_#{p}$/)}
21
+ predicate = Ransack.predicate_keys.detect {|p| original_name.match(/_#{p}$/)}
22
22
  attributes_str = original_name.sub(/_#{predicate}$/, '')
23
23
  attribute_names = attributes_str.split(/_and_|_or_/)
24
24
  combinator = attributes_str.match(/_and_/) ? :and : :or
@@ -1,3 +1,3 @@
1
1
  module Ransack
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -17,7 +17,11 @@ module Ransack
17
17
  object.arel_predicate if object.valid?
18
18
  end
19
19
 
20
- def visit_Ransack_Nodes_And(object)
20
+ def visit_Ransack_Nodes_Grouping(object)
21
+ object.combinator == 'or' ? visit_or(object) : visit_and(object)
22
+ end
23
+
24
+ def visit_and(object)
21
25
  nodes = object.values.map {|o| accept(o)}.compact
22
26
  return nil unless nodes.size > 0
23
27
 
@@ -28,11 +32,7 @@ module Ransack
28
32
  end
29
33
  end
30
34
 
31
- def visit_Ransack_Nodes_Sort(object)
32
- object.attr.send(object.dir) if object.valid?
33
- end
34
-
35
- def visit_Ransack_Nodes_Or(object)
35
+ def visit_or(object)
36
36
  nodes = object.values.map {|o| accept(o)}.compact
37
37
  return nil unless nodes.size > 0
38
38
 
@@ -43,6 +43,10 @@ module Ransack
43
43
  end
44
44
  end
45
45
 
46
+ def visit_Ransack_Nodes_Sort(object)
47
+ object.attr.send(object.dir) if object.valid?
48
+ end
49
+
46
50
  def quoted?(object)
47
51
  case object
48
52
  when Arel::Nodes::SqlLiteral, Bignum, Fixnum
@@ -2,9 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  module Ransack
4
4
  describe Configuration do
5
- it 'yields self on configure' do
6
- Ransack.configure do
7
- self.should eq Ransack::Configuration
5
+ it 'yields Ransack on configure' do
6
+ Ransack.configure do |config|
7
+ config.should eq Ransack
8
8
  end
9
9
  end
10
10
  end
@@ -32,12 +32,88 @@ module Ransack
32
32
 
33
33
  it 'selects previously-entered time values with datetime_select' do
34
34
  @s.created_at_eq = [2011, 1, 2, 3, 4, 5]
35
- html = @f.datetime_select :created_at_eq
36
- [2011, 1, 2, 3, 4, 5].each do |val|
37
- html.should match /<option selected="selected" value="#{val}">#{val}<\/option>/o
35
+ html = @f.datetime_select :created_at_eq, :use_month_numbers => true, :include_seconds => true
36
+ %w(2011 1 2 03 04 05).each do |val|
37
+ html.should match /<option selected="selected" value="#{val}">#{val}<\/option>/
38
38
  end
39
39
  end
40
40
 
41
+ describe '#label' do
42
+
43
+ it 'localizes attribute names' do
44
+ html = @f.label :name_cont
45
+ html.should match /Full Name contains/
46
+ end
47
+
48
+ end
49
+
50
+ describe '#submit' do
51
+
52
+ it 'localizes :search when no default value given' do
53
+ html = @f.submit
54
+ html.should match /"Search"/
55
+ end
56
+
57
+ end
58
+
59
+ describe '#attribute_select' do
60
+
61
+ it 'returns ransackable attributes' do
62
+ html = @f.attribute_select
63
+ html.split(/\n/).should have(Person.ransackable_attributes.size + 1).lines
64
+ Person.ransackable_attributes.each do |attribute|
65
+ html.should match /<option value="#{attribute}">/
66
+ end
67
+ end
68
+
69
+ it 'returns ransackable attributes for associations with :associations' do
70
+ attributes = Person.ransackable_attributes + Article.ransackable_attributes.map {|a| "articles_#{a}"}
71
+ html = @f.attribute_select :associations => ['articles']
72
+ html.split(/\n/).should have(attributes.size).lines
73
+ attributes.each do |attribute|
74
+ html.should match /<option value="#{attribute}">/
75
+ end
76
+ end
77
+
78
+ it 'returns option groups for base and associations with :associations' do
79
+ html = @f.attribute_select :associations => ['articles']
80
+ [Person, Article].each do |model|
81
+ html.should match /<optgroup label="#{model}">/
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ describe '#predicate_select' do
88
+
89
+ it 'returns predicates with predicate_select' do
90
+ html = @f.predicate_select
91
+ Ransack.predicate_keys.each do |key|
92
+ html.should match /<option value="#{key}">/
93
+ end
94
+ end
95
+
96
+ it 'filters predicates with single-value :only' do
97
+ html = @f.predicate_select :only => 'eq'
98
+ Ransack.predicate_keys.reject {|k| k =~ /^eq/}.each do |key|
99
+ html.should_not match /<option value="#{key}">/
100
+ end
101
+ end
102
+
103
+ it 'filters predicates with multi-value :only' do
104
+ html = @f.predicate_select :only => [:eq, :lt]
105
+ Ransack.predicate_keys.reject {|k| k =~ /^(eq|lt)/}.each do |key|
106
+ html.should_not match /<option value="#{key}">/
107
+ end
108
+ end
109
+
110
+ it 'excludes compounds when :compounds => false' do
111
+ html = @f.predicate_select :compounds => false
112
+ Ransack.predicate_keys.select {|k| k =~ /_(any|all)$/}.each do |key|
113
+ html.should_not match /<option value="#{key}">/
114
+ end
115
+ end
116
+ end
41
117
  end
42
118
  end
43
119
  end
@@ -39,30 +39,34 @@ module Ransack
39
39
 
40
40
  it 'accepts arrays of groupings' do
41
41
  search = Search.new(Person,
42
- :o => [
43
- {:name_eq => 'Ernie', :children_name_eq => 'Ernie'},
44
- {:name_eq => 'Bert', :children_name_eq => 'Bert'},
42
+ :g => [
43
+ {:m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie'},
44
+ {:m => 'or', :name_eq => 'Bert', :children_name_eq => 'Bert'},
45
45
  ]
46
46
  )
47
- ors = search.ors
47
+ ors = search.groupings
48
48
  ors.should have(2).items
49
49
  or1, or2 = ors
50
- or1.should be_a Nodes::Or
51
- or2.should be_a Nodes::Or
50
+ or1.should be_a Nodes::Grouping
51
+ or1.combinator.should eq 'or'
52
+ or2.should be_a Nodes::Grouping
53
+ or2.combinator.should eq 'or'
52
54
  end
53
55
 
54
56
  it 'accepts "attributes" hashes for groupings' do
55
57
  search = Search.new(Person,
56
- :o => {
57
- '0' => {:name_eq => 'Ernie', :children_name_eq => 'Ernie'},
58
- '1' => {:name_eq => 'Bert', :children_name_eq => 'Bert'},
58
+ :g => {
59
+ '0' => {:m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie'},
60
+ '1' => {:m => 'or', :name_eq => 'Bert', :children_name_eq => 'Bert'},
59
61
  }
60
62
  )
61
- ors = search.ors
63
+ ors = search.groupings
62
64
  ors.should have(2).items
63
65
  or1, or2 = ors
64
- or1.should be_a Nodes::Or
65
- or2.should be_a Nodes::Or
66
+ or1.should be_a Nodes::Grouping
67
+ or1.combinator.should eq 'or'
68
+ or2.should be_a Nodes::Grouping
69
+ or2.combinator.should eq 'or'
66
70
  end
67
71
 
68
72
  it 'accepts "attributes" hashes for conditions' do
@@ -102,7 +106,8 @@ module Ransack
102
106
 
103
107
  it 'evaluates nested conditions' do
104
108
  search = Search.new(Person, :children_name_eq => 'Ernie',
105
- :o => [{
109
+ :g => [{
110
+ :m => 'or',
106
111
  :name_eq => 'Ernie',
107
112
  :children_children_name_eq => 'Ernie'
108
113
  }]
@@ -114,9 +119,9 @@ module Ransack
114
119
 
115
120
  it 'evaluates arrays of groupings' do
116
121
  search = Search.new(Person,
117
- :o => [
118
- {:name_eq => 'Ernie', :children_name_eq => 'Ernie'},
119
- {:name_eq => 'Bert', :children_name_eq => 'Bert'},
122
+ :g => [
123
+ {:m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie'},
124
+ {:m => 'or', :name_eq => 'Bert', :children_name_eq => 'Bert'},
120
125
  ]
121
126
  )
122
127
  search.result.should be_an ActiveRecord::Relation
@@ -125,7 +130,7 @@ module Ransack
125
130
  end
126
131
 
127
132
  it 'returns distinct records when passed :distinct => true' do
128
- search = Search.new(Person, :o => [{:comments_body_cont => 'e', :articles_comments_body_cont => 'e'}])
133
+ search = Search.new(Person, :g => [{:m => 'or', :comments_body_cont => 'e', :articles_comments_body_cont => 'e'}])
129
134
  search.result.should have(920).items
130
135
  search.result(:distinct => true).should have(330).items
131
136
  search.result.all.uniq.should eq search.result(:distinct => true).all
@@ -195,9 +200,9 @@ module Ransack
195
200
  end
196
201
 
197
202
  it 'allows chaining to access nested conditions' do
198
- @s.ors = [{:name_eq => 'Ernie', :children_name_eq => 'Ernie'}]
199
- @s.ors.first.name_eq.should eq 'Ernie'
200
- @s.ors.first.children_name_eq.should eq 'Ernie'
203
+ @s.groupings = [{:m => 'or', :name_eq => 'Ernie', :children_name_eq => 'Ernie'}]
204
+ @s.groupings.first.name_eq.should eq 'Ernie'
205
+ @s.groupings.first.children_name_eq.should eq 'Ernie'
201
206
  end
202
207
  end
203
208
 
@@ -4,6 +4,7 @@ require 'faker'
4
4
  require 'ransack'
5
5
 
6
6
  Time.zone = 'Eastern Time (US & Canada)'
7
+ I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'support', '*.yml')]
7
8
 
8
9
  Dir[File.expand_path('../{helpers,support,blueprints}/*.rb', __FILE__)].each do |f|
9
10
  require f
@@ -0,0 +1,5 @@
1
+ en:
2
+ ransack:
3
+ attributes:
4
+ person:
5
+ name: Full Name
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: ransack
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.3.0
5
+ version: 0.4.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ernie Miller
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-30 00:00:00 Z
13
+ date: 2011-06-05 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -106,7 +106,6 @@ files:
106
106
  - Rakefile
107
107
  - lib/ransack.rb
108
108
  - lib/ransack/adapters/active_record.rb
109
- - lib/ransack/adapters/active_record/3.0/base.rb
110
109
  - lib/ransack/adapters/active_record/3.0/compat.rb
111
110
  - lib/ransack/adapters/active_record/3.0/context.rb
112
111
  - lib/ransack/adapters/active_record/3.0/join_association.rb
@@ -124,13 +123,11 @@ files:
124
123
  - lib/ransack/locale/en.yml
125
124
  - lib/ransack/naming.rb
126
125
  - lib/ransack/nodes.rb
127
- - lib/ransack/nodes/and.rb
128
126
  - lib/ransack/nodes/attribute.rb
129
127
  - lib/ransack/nodes/bindable.rb
130
128
  - lib/ransack/nodes/condition.rb
131
129
  - lib/ransack/nodes/grouping.rb
132
130
  - lib/ransack/nodes/node.rb
133
- - lib/ransack/nodes/or.rb
134
131
  - lib/ransack/nodes/sort.rb
135
132
  - lib/ransack/nodes/value.rb
136
133
  - lib/ransack/predicate.rb
@@ -157,6 +154,7 @@ files:
157
154
  - spec/ransack/predicate_spec.rb
158
155
  - spec/ransack/search_spec.rb
159
156
  - spec/spec_helper.rb
157
+ - spec/support/en.yml
160
158
  - spec/support/schema.rb
161
159
  homepage: http://metautonomo.us/projects/ransack
162
160
  licenses: []
@@ -203,4 +201,5 @@ test_files:
203
201
  - spec/ransack/predicate_spec.rb
204
202
  - spec/ransack/search_spec.rb
205
203
  - spec/spec_helper.rb
204
+ - spec/support/en.yml
206
205
  - spec/support/schema.rb
@@ -1,33 +0,0 @@
1
- module Ransack
2
- module Adapters
3
- module ActiveRecord
4
- module Base
5
-
6
- def self.extended(base)
7
- alias :search :ransack unless base.method_defined? :search
8
- base.instance_eval do
9
- class_attribute :_ransackers
10
- self._ransackers ||= {}
11
- end
12
- end
13
-
14
- def ransack(params = {}, options = {})
15
- Search.new(self, params, options)
16
- end
17
-
18
- def ransacker(name, opts = {}, &block)
19
- Ransacker.new(self, name, opts, &block)
20
- end
21
-
22
- def ransackable_attributes(auth_object)
23
- column_names + _ransackers.keys
24
- end
25
-
26
- def ransackable_associations(auth_object)
27
- reflect_on_all_associations.map {|a| a.name.to_s}
28
- end
29
-
30
- end
31
- end
32
- end
33
- end
@@ -1,8 +0,0 @@
1
- require 'ransack/nodes/grouping'
2
-
3
- module Ransack
4
- module Nodes
5
- class And < Grouping
6
- end
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- require 'ransack/nodes/grouping'
2
-
3
- module Ransack
4
- module Nodes
5
- class Or < Grouping
6
- end
7
- end
8
- end