ransack_ffcrm 0.6.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -3,19 +3,9 @@ gemspec
3
3
 
4
4
  gem 'rake'
5
5
 
6
- rails = ENV['RAILS'] || 'master'
7
- arel = ENV['AREL'] || 'master'
6
+ rails = ENV['RAILS'] || '3-2-stable'
8
7
 
9
- arel_opts = case arel
10
- when /\// # A path
11
- {:path => arel}
12
- when /^v/ # A tagged version
13
- {:git => 'git://github.com/rails/arel.git', :tag => arel}
14
- else
15
- {:git => 'git://github.com/rails/arel.git', :branch => arel}
16
- end
17
-
18
- gem 'arel', arel_opts
8
+ gem 'arel', '3.0.2'
19
9
 
20
10
  case rails
21
11
  when /\// # A path
data/README.md CHANGED
@@ -4,10 +4,10 @@ Ransack is a rewrite of [MetaSearch](http://metautonomo.us/projects/metasearch).
4
4
  supports many of the same features as MetaSearch, its underlying implementation differs
5
5
  greatly from MetaSearch, and _backwards compatibility is not a design goal._
6
6
 
7
- Ransack enables the creation of both simple and [advanced](http://ransack-demo.heroku.com)
7
+ Ransack enables the creation of both simple and [advanced](http://ransack-demo.herokuapp.com/users/advanced_search)
8
8
  search forms against your application's models. If you're looking for something that
9
9
  simplifies query generation at the model or controller layer, you're probably not looking
10
- for Ransack (or MetaSearch, for that matter). Try
10
+ for Ransack (or MetaSearch, for that matter). Try
11
11
  [Squeel](http://metautonomo.us/projects/squeel) instead.
12
12
 
13
13
  ## Getting started
@@ -15,27 +15,11 @@ for Ransack (or MetaSearch, for that matter). Try
15
15
  In your Gemfile:
16
16
 
17
17
  gem "ransack" # Last officially released gem
18
- # gem "ransack", :git => "git://github.com/ernie/ransack.git" # Track git repo
19
-
20
- If you'd like to add your own custom Ransack predicates:
21
-
22
- Ransack.configure do |config|
23
- config.add_predicate 'equals_diddly', # Name your predicate
24
- # What non-compound ARel predicate will it use? (eq, matches, etc)
25
- :arel_predicate => 'eq',
26
- # Format incoming values as you see fit. (Default: Don't do formatting)
27
- :formatter => proc {|v| "#{v}-diddly"},
28
- # Validate a value. An "invalid" value won't be used in a search.
29
- # Below is default.
30
- :validator => proc {|v| v.present?},
31
- # Should compounds be created? Will use the compound (any/all) version
32
- # of the arel_predicate to create a corresponding any/all version of
33
- # your predicate. (Default: true)
34
- :compounds => true,
35
- # Force a specific column type for type-casting of supplied values.
36
- # (Default: use type from DB column)
37
- :type => :string
38
- end
18
+
19
+ Or if you want to use the bleeding edge:
20
+
21
+ gem "ransack", :git => "git://github.com/ernie/ransack.git" # Track git repo
22
+
39
23
 
40
24
  ## Usage
41
25
 
@@ -49,9 +33,10 @@ requires very little setup effort.
49
33
  If you're coming from MetaSearch, things to note:
50
34
 
51
35
  1. The default param key for search params is now `:q`, instead of `:search`. This is
52
- primarily to shorten query strings, though advanced queries (below) will still
53
- run afoul of URL length limits in most browsers and require a switch to HTTP
54
- POST requests.
36
+ primarily to shorten query strings, though advanced queries (below) will still
37
+ run afoul of URL length limits in most browsers and require a switch to HTTP
38
+ POST requests. This key is
39
+ [configurable](https://github.com/ernie/ransack/wiki/Configuration)
55
40
  2. `form_for` is now `search_form_for`, and validates that a Ransack::Search object
56
41
  is passed to it.
57
42
  3. Common ActiveRecord::Relation methods are no longer delegated by the search object.
@@ -59,7 +44,7 @@ If you're coming from MetaSearch, things to note:
59
44
  the ActiveRecord adapter) via a call to `Search#result`. If passed `:distinct => true`,
60
45
  `result` will generate a `SELECT DISTINCT` to avoid returning duplicate rows, even if
61
46
  conditions on a join would otherwise result in some.
62
-
47
+
63
48
  Please note that for many databases, a sort on an associated table's columns will
64
49
  result in invalid SQL with `:distinct => true` -- in those cases, you're on your own,
65
50
  and will need to modify the result as needed to allow these queries to work. Thankfully,
@@ -84,8 +69,8 @@ In your view:
84
69
  <% end %>
85
70
 
86
71
  `cont` (contains) and `start` (starts with) are just two of the available search predicates.
87
- See Constants for a full list.
88
-
72
+ See [Constants](https://github.com/ernie/ransack/blob/master/lib/ransack/constants.rb) for a full list and the [wiki](https://github.com/ernie/ransack/wiki/Basic-Searching) for more description.
73
+
89
74
  ### Advanced Mode
90
75
 
91
76
  "Advanced" searches (ab)use Rails' nested attributes functionality in order to generate
@@ -108,30 +93,75 @@ This means you'll need to tweak your routes...
108
93
  index
109
94
  render :index
110
95
  end
111
-
96
+
112
97
  ... and update your `search_form_for` line in the view ...
113
98
 
114
- <%= search_form_for @q, :url => search_people_path,
99
+ <%= search_form_for @q, :url => search_people_path,
115
100
  :html => {:method => :post} do |f| %>
116
101
 
117
102
  Once you've done so, you can make use of the helpers in Ransack::Helpers::FormBuilder to
118
103
  construct much more complex search forms, such as the one on the
119
104
  [demo page](http://ransack-demo.heroku.com).
120
105
 
121
- **more docs to come**
106
+ ### has_many and belongs_to associations
122
107
 
123
- ## Contributions
108
+ You can easily use Ransack to search in associated objects.
109
+
110
+ Given you have these associations ...
111
+
112
+ class Employee < ActiveRecord::Base
113
+ belongs_to :supervisor
114
+
115
+ # has attribute last_name:string
116
+ end
117
+
118
+ class Department < ActiveRecord::Base
119
+ has_many :supervisors
120
+
121
+ # has attribute title:string
122
+ end
124
123
 
125
- If you'd like to support the continued development of Ransack, please consider
126
- [making a donation](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=48Q9HY64L3TWA).
124
+ class Supervisor < ActiveRecord::Base
125
+ belongs_to :department
126
+ has_many :employees
127
+
128
+ # has attribute last_name:string
129
+ end
130
+
131
+ ... and a controller ...
132
+
133
+ class SupervisorsController < ApplicationController
134
+ def index
135
+ @search = Supervisor.search(params[:q])
136
+ @supervisors = @search.result(:distinct => true)
137
+ end
138
+ end
139
+
140
+ ... you might set up your form like this ...
141
+
142
+ <%= search_form_for @search do |f| %>
143
+ <%= f.label :last_name_cont %>
144
+ <%= f.text_field :last_name_cont %>
145
+
146
+ <%= f.label :department_title_cont %>
147
+ <%= f.text_field :department_title_cont %>
148
+
149
+ <%= f.label :employees_last_name_cont %>
150
+ <%= f.text_field :employees_last_name_cont %>
151
+
152
+ <%= f.submit "search" %>
153
+ <% end %>
154
+
155
+
156
+ ## Contributions
127
157
 
128
- To support the project in other ways:
158
+ To support the project:
129
159
 
130
- * Use Ransack in your apps, and let me know if you encounter anything that's broken or missing.
160
+ * Use Ransack in your apps, and let us know if you encounter anything that's broken or missing.
131
161
  A failing spec is awesome. A pull request is even better!
132
162
  * Spread the word on Twitter, Facebook, and elsewhere if Ransack's been useful to you. The more
133
163
  people who are using the project, the quicker we can find and fix bugs!
134
164
 
135
165
  ## Copyright
136
166
 
137
- Copyright &copy; 2011 [Ernie Miller](http://twitter.com/erniemiller)
167
+ Copyright &copy; 2011 [Ernie Miller](http://twitter.com/erniemiller)
@@ -138,7 +138,7 @@ module Ransack
138
138
  )
139
139
 
140
140
  join_nodes.each do |join|
141
- join_dependency.table_aliases[join.left.name.downcase] = 1
141
+ join_dependency.alias_tracker.aliases[join.left.name.downcase] = 1
142
142
  end
143
143
 
144
144
  join_dependency.graft(*stashed_association_joins)
@@ -0,0 +1,14 @@
1
+ module Arel
2
+
3
+ module Visitors
4
+
5
+ class DepthFirst < Visitor
6
+
7
+ unless method_defined?(:visit_Arel_Nodes_InfixOperation)
8
+ alias :visit_Arel_Nodes_InfixOperation :binary
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -1,19 +1,20 @@
1
1
  require 'ransack/context'
2
2
  require 'ransack/adapters/active_record/3.1/context'
3
+ require 'ransack/adapters/active_record/compat'
3
4
  require 'polyamorous'
4
5
 
5
6
  module Ransack
6
7
  module Adapters
7
8
  module ActiveRecord
8
9
  class Context < ::Ransack::Context
9
-
10
+
10
11
  # Redefine a few things that have changed with 3.2.
11
-
12
+
12
13
  def initialize(object, options = {})
13
14
  super
14
15
  @arel_visitor = @engine.connection.visitor
15
16
  end
16
-
17
+
17
18
  def type_for(attr)
18
19
  return nil unless attr && attr.valid?
19
20
  name = attr.arel_attribute.name.to_s
@@ -25,7 +26,7 @@ module Ransack
25
26
 
26
27
  @engine.connection.schema_cache.columns_hash[table][name].type
27
28
  end
28
-
29
+
29
30
  def evaluate(search, opts = {})
30
31
  viz = Visitor.new
31
32
  relation = @object.where(viz.accept(search.base))
@@ -34,7 +35,7 @@ module Ransack
34
35
  end
35
36
  opts[:distinct] ? relation.uniq : relation
36
37
  end
37
-
38
+
38
39
  end
39
40
  end
40
41
  end
@@ -4,8 +4,11 @@ require 'ransack/predicate'
4
4
  module Ransack
5
5
  module Configuration
6
6
 
7
- mattr_accessor :predicates
7
+ mattr_accessor :predicates, :options
8
8
  self.predicates = {}
9
+ self.options = {
10
+ :search_key => :q
11
+ }
9
12
 
10
13
  def configure
11
14
  yield self
@@ -16,6 +19,7 @@ module Ransack
16
19
  opts[:name] = name
17
20
  compounds = opts.delete(:compounds)
18
21
  compounds = true if compounds.nil?
22
+ compounds = false if opts[:wants_array]
19
23
  opts[:arel_predicate] = opts[:arel_predicate].to_s
20
24
 
21
25
  self.predicates[name] = Predicate.new(opts)
@@ -31,5 +35,10 @@ module Ransack
31
35
  end if compounds
32
36
  end
33
37
 
38
+ # default search_key that, it can be overridden on sort_link level
39
+ def search_key=(name)
40
+ self.options[:search_key] = name
41
+ end
42
+
34
43
  end
35
- end
44
+ end
@@ -3,7 +3,7 @@ require 'ransack/visitor'
3
3
  module Ransack
4
4
  class Context
5
5
  attr_reader :search, :object, :klass, :base, :engine, :arel_visitor
6
- attr_accessor :auth_object
6
+ attr_accessor :auth_object, :search_key
7
7
 
8
8
  class << self
9
9
 
@@ -32,6 +32,7 @@ module Ransack
32
32
  @klass = @object.klass
33
33
  @join_dependency = join_dependency(@object)
34
34
  @join_type = options[:join_type] || Arel::OuterJoin
35
+ @search_key = options[:search_key] || Ransack.options[:search_key]
35
36
  @base = @join_dependency.join_base
36
37
  @engine = @base.arel_engine
37
38
  @default_table = Arel::Table.new(@base.table_name, :as => @base.aliased_table_name, :engine => @engine)
@@ -13,8 +13,8 @@ module Ransack
13
13
  end
14
14
  options[:html] ||= {}
15
15
  html_options = {
16
- :class => options[:as] ? "#{options[:as]}_search" : "#{search.klass.to_s.underscore}_search",
17
- :id => options[:as] ? "#{options[:as]}_search" : "#{search.klass.to_s.underscore}_search",
16
+ :class => options[:class].present? ? "#{options[:class]}" : "#{search.klass.to_s.underscore}_search",
17
+ :id => options[:id].present? ? "#{options[:id]}" : "#{search.klass.to_s.underscore}_search",
18
18
  :method => :get
19
19
  }
20
20
  options[:as] ||= 'q'
@@ -25,9 +25,15 @@ module Ransack
25
25
  end
26
26
 
27
27
  def sort_link(search, attribute, *args)
28
+ # Extract out a routing proxy for url_for scoping later
29
+ if search.is_a?(Array)
30
+ routing_proxy = search.shift
31
+ search = search.first
32
+ end
33
+
28
34
  raise TypeError, "First argument must be a Ransack::Search!" unless Search === search
29
35
 
30
- search_params = params[:q] || {}.with_indifferent_access
36
+ search_params = params[search.context.search_key] || {}.with_indifferent_access
31
37
 
32
38
  attr_name = attribute.to_s
33
39
 
@@ -50,12 +56,19 @@ module Ransack
50
56
  html_options = args.first.is_a?(Hash) ? args.shift.dup : {}
51
57
  css = ['sort_link', current_dir].compact.join(' ')
52
58
  html_options[:class] = [css, html_options[:class]].compact.join(' ')
53
- options.merge!(
54
- :q => search_params.merge(:s => "#{attr_name} #{new_dir}")
55
- )
59
+ query_hash = {}
60
+ query_hash[search.context.search_key] = search_params.merge(:s => "#{attr_name} #{new_dir}")
61
+ options.merge!(query_hash)
62
+
63
+ url = if routing_proxy && respond_to?(routing_proxy)
64
+ send(routing_proxy).url_for(options)
65
+ else
66
+ url_for(options)
67
+ end
68
+
56
69
  link_to [ERB::Util.h(name), order_indicator_for(current_dir)].compact.join(' ').html_safe,
57
- url_for(options),
58
- html_options
70
+ url,
71
+ html_options
59
72
  end
60
73
 
61
74
  private
@@ -72,4 +85,4 @@ module Ransack
72
85
 
73
86
  end
74
87
  end
75
- end
88
+ end
@@ -0,0 +1,70 @@
1
+ cs:
2
+ ransack:
3
+ search: "vyhledávání"
4
+ predicate: "predikát"
5
+ and: "a"
6
+ or: "nebo"
7
+ any: "kteroukoliv"
8
+ all: "každou"
9
+ combinator: "kombinátor"
10
+ attribute: "atribut"
11
+ value: "hodnota"
12
+ condition: "podmínka"
13
+ sort: "řazení"
14
+ asc: "vzestupné"
15
+ desc: "sestupné"
16
+ predicates:
17
+ eq: "rovno"
18
+ eq_any: "rovno kterékoliv"
19
+ eq_all: "rovno všem"
20
+ not_eq: "nerovno"
21
+ not_eq_any: "nerovno kterékoliv"
22
+ not_eq_all: "nerovno všem"
23
+ matches: "odpovídá"
24
+ matches_any: "odpovídá kterékoliv"
25
+ matches_all: "odpovídá všem"
26
+ does_not_match: "neodpovídá"
27
+ does_not_match_any: "neodpovídá kterékoliv"
28
+ does_not_match_all: "neodpovídá všem"
29
+ lt: "menší než"
30
+ lt_any: "menší než kterákoliv"
31
+ lt_all: "menší než všechny"
32
+ lteq: "menší nebo rovno než"
33
+ lteq_any: "menší nebo rovno než kterákoliv"
34
+ lteq_all: "menší nebo rovno než všechny"
35
+ gt: "větší než"
36
+ gt_any: "větší než kterákoliv"
37
+ gt_all: "větší než všechny"
38
+ gteq: "větší nebo rovno než"
39
+ gteq_any: "větší nebo rovno než kterákoliv"
40
+ gteq_all: "větší nebo rovno než všechny"
41
+ in: "v"
42
+ in_any: "v kterékoliv"
43
+ in_all: "ve všech"
44
+ not_in: "není v"
45
+ not_in_any: "není v kterékoliv"
46
+ not_in_all: "není ve všech"
47
+ cont: "obsahuje"
48
+ cont_any: "obsahuje kterékoliv"
49
+ cont_all: "obsahuje všechny"
50
+ not_cont: "neobsahuje"
51
+ not_cont_any: "neobsahuje kteroukoliv"
52
+ not_cont_all: "neobsahuje všechny"
53
+ start: "začíná s"
54
+ start_any: "začíná s kteroukoliv"
55
+ start_all: "začíná se všemi"
56
+ not_start: "nezačíná s"
57
+ not_start_any: "nezačíná s kteroukoliv"
58
+ not_start_all: "nezačíná se všemi"
59
+ end: "končí s"
60
+ end_any: "končí s kteroukoliv"
61
+ end_all: "končí se všemi"
62
+ not_end: "nekončí s"
63
+ not_end_any: "nekončí s kteroukoliv"
64
+ not_end_all: "nekončí se všemi"
65
+ 'true': "je pravdivé"
66
+ 'false': "není pravdivé"
67
+ present: "je vyplněné"
68
+ blank: "je prázdné"
69
+ 'null': "je null"
70
+ not_null: "není null"
@@ -0,0 +1,70 @@
1
+ es:
2
+ ransack:
3
+ search: "buscar"
4
+ predicate: "predicado"
5
+ and: "y"
6
+ or: "o"
7
+ any: "cualquier"
8
+ all: "todos"
9
+ combinator: "combinado"
10
+ attribute: "atributo"
11
+ value: "valor"
12
+ condition: "condición"
13
+ sort: "ordernar"
14
+ asc: "ascendente"
15
+ desc: "descendente"
16
+ predicates:
17
+ eq: "es igual a"
18
+ eq_any: "es igual a cualquier"
19
+ eq_all: "es igual a todos"
20
+ not_eq: "no es igual a"
21
+ not_eq_any: "no es igual a cualquier"
22
+ not_eq_all: "no es iguala todos"
23
+ matches: "coincidir"
24
+ matches_any: "coincidir a cualquier"
25
+ matches_all: "coincidir a todos"
26
+ does_not_match: "no coincide"
27
+ does_not_match_any: "no coincide con ninguna"
28
+ does_not_match_all: "no coincide con todos"
29
+ lt: "menor que"
30
+ lt_any: "menor que cualquier"
31
+ lt_all: "menor o igual a"
32
+ lteq: "less than or equal to"
33
+ lteq_any: "menor o igual a cualquier"
34
+ lteq_all: "menor o igual a todos"
35
+ gt: "mayor que"
36
+ gt_any: "mayor que cualquier"
37
+ gt_all: "mayor que todos"
38
+ gteq: "mayor que o igual a"
39
+ gteq_any: "mayor que o igual a cualquier"
40
+ gteq_all: "mayor que o igual a todos"
41
+ in: "en"
42
+ in_any: "en cualquier"
43
+ in_all: "en todos"
44
+ not_in: "no en"
45
+ not_in_any: "no en cualquier"
46
+ not_in_all: "no en todos"
47
+ cont: "contiene"
48
+ cont_any: "contiene cualquier"
49
+ cont_all: "contiene todos"
50
+ not_cont: "no contiene"
51
+ not_cont_any: "no contiene ninguna"
52
+ not_cont_all: "no contiene toda"
53
+ start: "comienza con"
54
+ start_any: "comienza con cualquier"
55
+ start_all: "comienza con toda"
56
+ not_start: "no inicia con"
57
+ not_start_any: "no comienza con cualquier"
58
+ not_start_all: "no inicia con toda"
59
+ end: "termina con"
60
+ end_any: "termina con cualquier"
61
+ end_all: "termina con todo"
62
+ not_end: "no termina con"
63
+ not_end_any: "no termina con cualquier"
64
+ not_end_all: "no termina con todo"
65
+ 'true': "es verdadero"
66
+ 'false': "es falso"
67
+ present: "es presente"
68
+ blank: "está en blanco"
69
+ 'null': "es nula"
70
+ not_null: "no es nula"
@@ -44,6 +44,10 @@ module Ransack
44
44
  false
45
45
  end
46
46
 
47
+ def inspect
48
+ "Attribute <#{name}>"
49
+ end
50
+
47
51
  end
48
52
  end
49
53
  end
@@ -200,6 +200,13 @@ module Ransack
200
200
  predicate.type || (attributes.first && attributes.first.type)
201
201
  end
202
202
 
203
+ def inspect
204
+ data =[['attributes', a.try(:map, &:name)], ['predicate', p], ['combinator', m], ['values', v.try(:map, &:value)]].reject { |e|
205
+ e[1].blank?
206
+ }.map { |v| "#{v[0]}: #{v[1]}" }.join(', ')
207
+ "Condition <#{data}>"
208
+ end
209
+
203
210
  private
204
211
 
205
212
  def valid_combinator?
@@ -155,6 +155,13 @@ module Ransack
155
155
  self
156
156
  end
157
157
 
158
+ def inspect
159
+ data =[['conditions', conditions], ['combinator', combinator]].reject { |e|
160
+ e[1].blank?
161
+ }.map { |v| "#{v[0]}: #{v[1]}" }.join(', ')
162
+ "Grouping <#{data}>"
163
+ end
164
+
158
165
  private
159
166
 
160
167
  def write_attribute(name, val)
@@ -100,6 +100,10 @@ module Ransack
100
100
  end
101
101
  end
102
102
 
103
+ def inspect
104
+ "Value <#{value}>"
105
+ end
106
+
103
107
  def array_of_arrays?(val)
104
108
  Array === val && Array === val.first
105
109
  end
@@ -41,7 +41,7 @@ module Ransack
41
41
  @formatter = opts[:formatter]
42
42
  @validator = opts[:validator] || lambda { |v| v.respond_to?(:empty?) ? !v.empty? : !v.nil? }
43
43
  @compound = opts[:compound]
44
- @wants_array = @compound || ['in', 'not_in'].include?(@arel_predicate)
44
+ @wants_array = opts[:wants_array] == true || @compound || ['in', 'not_in'].include?(@arel_predicate)
45
45
  end
46
46
 
47
47
  def eql?(other)
@@ -78,7 +78,7 @@ module Ransack
78
78
  Nodes::Sort.new(@context).build(opts)
79
79
  end
80
80
 
81
- def respond_to?(method_id)
81
+ def respond_to?(method_id, include_private = false)
82
82
  super or begin
83
83
  method_name = method_id.to_s
84
84
  writer = method_name.sub!(/\=$/, '')
@@ -96,6 +96,10 @@ module Ransack
96
96
  end
97
97
  end
98
98
 
99
+ def inspect
100
+ "Ransack::Search<class: #{klass.name}, base: #{base.inspect}>"
101
+ end
102
+
99
103
  private
100
104
 
101
105
  def collapse_multiparameter_attributes!(attrs)
@@ -120,4 +124,4 @@ module Ransack
120
124
  end
121
125
 
122
126
  end
123
- end
127
+ end
@@ -1,3 +1,3 @@
1
1
  module Ransack
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.1"
3
3
  end
@@ -6,9 +6,9 @@ Gem::Specification.new do |s|
6
6
  s.name = "ransack_ffcrm"
7
7
  s.version = Ransack::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
- s.authors = ["Ernie Miller"]
10
- s.email = ["ernie@metautonomo.us"]
11
- s.homepage = "http://metautonomo.us/projects/ransack"
9
+ s.authors = ["Ernie Miller", "Ryan Bigg"]
10
+ s.email = ["ernie@erniemiller.org", "radarlistener@gmail.com"]
11
+ s.homepage = "https://github.com/ernie/ransack"
12
12
  s.summary = %q{Object-based searching for ActiveRecord (currently).}
13
13
  s.description = %q{Ransack is the successor to the MetaSearch gem. It improves and expands upon MetaSearch's functionality, but does not have a 100%-compatible API.}
14
14
 
@@ -43,6 +43,11 @@ module Ransack
43
43
  s = Person.search(:doubled_name_eq => 'Aric SmithAric Smith')
44
44
  s.result.first.should eq Person.find_by_name('Aric Smith')
45
45
  end if defined?(Arel::Nodes::InfixOperation)
46
+
47
+ it "doesn't break #count if using InfixOperations" do
48
+ s = Person.search(:doubled_name_eq => 'Aric SmithAric Smith')
49
+ s.result.count.should eq 1
50
+ end if defined?(Arel::Nodes::InfixOperation)
46
51
  end
47
52
 
48
53
  describe '#ransackable_attributes' do
@@ -27,5 +27,33 @@ module Ransack
27
27
  Ransack.predicates.should_not have_key 'test_predicate_without_compound_any'
28
28
  Ransack.predicates.should_not have_key 'test_predicate_without_compound_all'
29
29
  end
30
+
31
+ it 'should have default value for search key' do
32
+ Ransack.options[:search_key].should eq :q
33
+ end
34
+
35
+ it 'changes default search key parameter' do
36
+ # store original state so we can restore it later
37
+ before = Ransack.options.clone
38
+
39
+ Ransack.configure do |config|
40
+ config.search_key = :query
41
+ end
42
+
43
+ Ransack.options[:search_key].should eq :query
44
+
45
+ # restore original state so we don't break other tests
46
+ Ransack.options = before
47
+ end
48
+
49
+ it 'adds predicates that take arrays, overriding compounds' do
50
+ Ransack.configure do |config|
51
+ config.add_predicate :test_array_predicate, :wants_array => true, :compounds => true
52
+ end
53
+
54
+ Ransack.predicates['test_array_predicate'].wants_array.should eq true
55
+ Ransack.predicates.should_not have_key 'test_array_predicate_any'
56
+ Ransack.predicates.should_not have_key 'test_array_predicate_all'
57
+ end
30
58
  end
31
59
  end
@@ -25,14 +25,26 @@ module Ransack
25
25
  end
26
26
  end
27
27
 
28
- describe '#sort_link' do
29
- subject { @controller.view_context.sort_link(Person.search(:sorts => ['name desc']), :name, :controller => 'people') }
28
+ describe '#sort_link with default search_key' do
29
+ subject { @controller.view_context.sort_link([:main_app, Person.search(:sorts => ['name desc'])], :name, :controller => 'people') }
30
+ it { should match /people\?q%5Bs%5D=name\+asc/ }
31
+ it { should match /sort_link desc/ }
32
+ it { should match /Full Name &#9660;/ }
33
+ end
34
+
35
+ describe '#sort_link with default search_key defined as symbol' do
36
+ subject { @controller.view_context.sort_link(Person.search({:sorts => ['name desc']}, :search_key => :people_search),
37
+ :name, :controller => 'people') }
30
38
 
31
- it { should match /people\?q%5Bs%5D=name\+asc/}
32
- it { should match /sort_link desc/}
33
- it { should match /Full Name &#9660;/}
39
+ it { should match /people\?people_search%5Bs%5D=name\+asc/ }
34
40
  end
35
41
 
42
+ describe '#sort_link with default search_key defined as string' do
43
+ subject { @controller.view_context.sort_link(Person.search({:sorts => ['name desc']}, :search_key => 'people_search'),
44
+ :name, :controller => 'people') }
45
+
46
+ it { should match /people\?people_search%5Bs%5D=name\+asc/ }
47
+ end
36
48
  end
37
49
  end
38
- end
50
+ end
@@ -90,6 +90,25 @@ module Ransack
90
90
  conditions.should have(2).items
91
91
  conditions.map {|c| c.class}.should eq [Nodes::Condition, Nodes::Condition]
92
92
  end
93
+
94
+ it 'creates Conditions for custom predicates that take arrays' do
95
+ Ransack.configure do |config|
96
+ config.add_predicate 'ary_pred',
97
+ :wants_array => true
98
+ end
99
+
100
+ search = Search.new(Person, :name_ary_pred => ['Ernie', 'Bert'])
101
+ condition = search.base[:name_ary_pred]
102
+ condition.should be_a Nodes::Condition
103
+ condition.predicate.name.should eq 'ary_pred'
104
+ condition.attributes.first.name.should eq 'name'
105
+ condition.value.should eq ['Ernie', 'Bert']
106
+ end
107
+
108
+ it 'does not evaluate the query on #inspect' do
109
+ search = Search.new(Person, :children_id_in => [1, 2, 3])
110
+ search.inspect.should_not match /ActiveRecord/
111
+ end
93
112
  end
94
113
 
95
114
  describe '#result' do
@@ -221,5 +240,11 @@ module Ransack
221
240
  end
222
241
  end
223
242
 
243
+ describe '#respond_to' do
244
+ it 'is aware of second argument' do
245
+ Search.new(Person).respond_to?(:name_eq, true).should be_true
246
+ end
247
+ end
248
+
224
249
  end
225
250
  end
@@ -44,4 +44,4 @@ RSpec::Matchers.define :have_attribute_method do |expected|
44
44
  match do |actual|
45
45
  actual.attribute_method?(expected)
46
46
  end
47
- end
47
+ end
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ransack_ffcrm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ernie Miller
9
+ - Ryan Bigg
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2012-05-08 00:00:00.000000000 Z
13
+ date: 2012-11-06 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: activerecord
@@ -142,7 +143,8 @@ dependencies:
142
143
  description: Ransack is the successor to the MetaSearch gem. It improves and expands
143
144
  upon MetaSearch's functionality, but does not have a 100%-compatible API.
144
145
  email:
145
- - ernie@metautonomo.us
146
+ - ernie@erniemiller.org
147
+ - radarlistener@gmail.com
146
148
  executables: []
147
149
  extensions: []
148
150
  extra_rdoc_files: []
@@ -159,6 +161,7 @@ files:
159
161
  - lib/ransack/adapters/active_record/3.0/context.rb
160
162
  - lib/ransack/adapters/active_record/3.1/context.rb
161
163
  - lib/ransack/adapters/active_record/base.rb
164
+ - lib/ransack/adapters/active_record/compat.rb
162
165
  - lib/ransack/adapters/active_record/context.rb
163
166
  - lib/ransack/configuration.rb
164
167
  - lib/ransack/constants.rb
@@ -166,7 +169,9 @@ files:
166
169
  - lib/ransack/helpers.rb
167
170
  - lib/ransack/helpers/form_builder.rb
168
171
  - lib/ransack/helpers/form_helper.rb
172
+ - lib/ransack/locale/cs.yml
169
173
  - lib/ransack/locale/en.yml
174
+ - lib/ransack/locale/es.yml
170
175
  - lib/ransack/naming.rb
171
176
  - lib/ransack/nodes.rb
172
177
  - lib/ransack/nodes/attribute.rb
@@ -202,7 +207,7 @@ files:
202
207
  - spec/spec_helper.rb
203
208
  - spec/support/en.yml
204
209
  - spec/support/schema.rb
205
- homepage: http://metautonomo.us/projects/ransack
210
+ homepage: https://github.com/ernie/ransack
206
211
  licenses: []
207
212
  post_install_message:
208
213
  rdoc_options: []
@@ -214,12 +219,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
214
219
  - - ! '>='
215
220
  - !ruby/object:Gem::Version
216
221
  version: '0'
222
+ segments:
223
+ - 0
224
+ hash: -3839595189433610283
217
225
  required_rubygems_version: !ruby/object:Gem::Requirement
218
226
  none: false
219
227
  requirements:
220
228
  - - ! '>='
221
229
  - !ruby/object:Gem::Version
222
230
  version: '0'
231
+ segments:
232
+ - 0
233
+ hash: -3839595189433610283
223
234
  requirements: []
224
235
  rubyforge_project: ransack
225
236
  rubygems_version: 1.8.24