ransack 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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