ransack 0.7.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ae3f27c548f10f431a0d5c13b3a9863d7e707e73
4
+ data.tar.gz: 83840f65158cb74f04e8bd5e0b63d1251bcd3272
5
+ SHA512:
6
+ metadata.gz: 1883d781609fbae07044a265169f8960c4416e2836d3c332ad66ffb2ec8a4427bd8f3114d7539bb62f7ed0d132478004751763bb51d96e782b6ca904f0d82f88
7
+ data.tar.gz: 8a817a0a03b09622c527a63c24502d3c9da37c46096ccf376a2577cf05d54c6302c9ba13e866dc2789f79e588c2b262a5e799760a15dfeae0c9339da6d016f8a
data/.travis.yml CHANGED
@@ -1,9 +1,16 @@
1
1
  rvm:
2
2
  - 1.8.7
3
3
  - 1.9.2
4
- - ree
5
- - rbx-18mode
6
- - ruby-head
4
+ - 1.9.3
5
+ - 2.0.0
7
6
 
8
7
  env:
8
+ - RAILS=4-0-stable
9
9
  - RAILS=3-2-stable
10
+ - RAILS=3-1-stable
11
+ - RAILS=3-0-stable
12
+
13
+ matrix:
14
+ exclude:
15
+ - rvm: 1.8.7
16
+ env: RAILS=4-0-stable
data/CONTRIBUTING.md CHANGED
@@ -24,8 +24,7 @@ Here's a quick guide:
24
24
  to know that you have a clean slate:
25
25
 
26
26
  $ bundle install
27
- $ bundle exec rake test_app
28
- $ bundle exec rake
27
+ $ bundle exec rake spec
29
28
 
30
29
  3. Add a test for your change. Only refactoring and documentation changes
31
30
  require no new tests. If you are adding functionality or fixing a bug, we need
data/Gemfile CHANGED
@@ -1,11 +1,11 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
  gemspec
3
3
 
4
4
  gem 'rake'
5
5
 
6
- rails = ENV['RAILS'] || '3-2-stable'
6
+ rails = ENV['RAILS'] || '4-0-stable'
7
7
 
8
- gem 'arel', '3.0.2'
8
+ gem 'arel'
9
9
 
10
10
  case rails
11
11
  when /\// # A path
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Ransack
2
2
 
3
- Ransack is a rewrite of [MetaSearch](http://metautonomo.us/projects/metasearch). While it
3
+ [![Build Status](https://travis-ci.org/ernie/ransack.png?branch=master)](https://travis-ci.org/ernie/ransack)
4
+
5
+ Ransack is a rewrite of [MetaSearch](https://github.com/ernie/meta_search). While it
4
6
  supports many of the same features as MetaSearch, its underlying implementation differs
5
7
  greatly from MetaSearch, and _backwards compatibility is not a design goal._
6
8
 
@@ -8,18 +10,21 @@ Ransack enables the creation of both simple and [advanced](http://ransack-demo.h
8
10
  search forms against your application's models. If you're looking for something that
9
11
  simplifies query generation at the model or controller layer, you're probably not looking
10
12
  for Ransack (or MetaSearch, for that matter). Try
11
- [Squeel](http://metautonomo.us/projects/squeel) instead.
13
+ [Squeel](https://github.com/ernie/squeel) instead.
12
14
 
13
15
  ## Getting started
14
16
 
15
17
  In your Gemfile:
16
18
 
17
- gem "ransack" # Last officially released gem
19
+ ```ruby
20
+ gem "ransack" # Last officially released gem (Rails 3 and 4)
21
+ ```
18
22
 
19
23
  Or if you want to use the bleeding edge:
20
24
 
21
- gem "ransack", :git => "git://github.com/ernie/ransack.git" # Track git repo
22
-
25
+ ```ruby
26
+ gem "ransack", github: "ernie/ransack" # Track git repo
27
+ ```
23
28
 
24
29
  ## Usage
25
30
 
@@ -41,32 +46,36 @@ If you're coming from MetaSearch, things to note:
41
46
  is passed to it.
42
47
  3. Common ActiveRecord::Relation methods are no longer delegated by the search object.
43
48
  Instead, you will get your search results (an ActiveRecord::Relation in the case of
44
- the ActiveRecord adapter) via a call to `Search#result`. If passed `:distinct => true`,
49
+ the ActiveRecord adapter) via a call to `Search#result`. If passed `distinct: true`,
45
50
  `result` will generate a `SELECT DISTINCT` to avoid returning duplicate rows, even if
46
51
  conditions on a join would otherwise result in some.
47
52
 
48
53
  Please note that for many databases, a sort on an associated table's columns will
49
- result in invalid SQL with `:distinct => true` -- in those cases, you're on your own,
54
+ result in invalid SQL with `distinct: true` -- in those cases, you're on your own,
50
55
  and will need to modify the result as needed to allow these queries to work. Thankfully,
51
56
  9 times out of 10, sort against the search's base is sufficient, though, as that's
52
57
  generally what's being displayed on your results page.
53
58
 
54
59
  In your controller:
55
60
 
56
- def index
57
- @q = Person.search(params[:q])
58
- @people = @q.result(:distinct => true)
59
- end
61
+ ```ruby
62
+ def index
63
+ @q = Person.search(params[:q])
64
+ @people = @q.result(distinct: true)
65
+ end
66
+ ```
60
67
 
61
68
  In your view:
62
69
 
63
- <%= search_form_for @q do |f| %>
64
- <%= f.label :name_cont %>
65
- <%= f.text_field :name_cont %>
66
- <%= f.label :articles_title_start %>
67
- <%= f.text_field :articles_title_start %>
68
- <%= f.submit %>
69
- <% end %>
70
+ ```erb
71
+ <%= search_form_for @q do |f| %>
72
+ <%= f.label :name_cont %>
73
+ <%= f.text_field :name_cont %>
74
+ <%= f.label :articles_title_start %>
75
+ <%= f.text_field :articles_title_start %>
76
+ <%= f.submit %>
77
+ <% end %>
78
+ ```
70
79
 
71
80
  `cont` (contains) and `start` (starts with) are just two of the available search predicates.
72
81
  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.
@@ -81,23 +90,29 @@ parameter string will typically force you to use the HTTP POST method instead of
81
90
 
82
91
  This means you'll need to tweak your routes...
83
92
 
84
- resources :people do
85
- collection do
86
- match 'search' => 'people#search', :via => [:get, :post], :as => :search
87
- end
88
- end
93
+ ```ruby
94
+ resources :people do
95
+ collection do
96
+ match 'search' => 'people#search', via: [:get, :post], as: :search
97
+ end
98
+ end
99
+ ```
89
100
 
90
101
  ... and add another controller action ...
91
102
 
92
- def search
93
- index
94
- render :index
95
- end
103
+ ```ruby
104
+ def search
105
+ index
106
+ render :index
107
+ end
108
+ ```
96
109
 
97
110
  ... and update your `search_form_for` line in the view ...
98
111
 
99
- <%= search_form_for @q, :url => search_people_path,
100
- :html => {:method => :post} do |f| %>
112
+ ```erb
113
+ <%= search_form_for @q, url: search_people_path,
114
+ html: { method: :post } do |f| %>
115
+ ```
101
116
 
102
117
  Once you've done so, you can make use of the helpers in Ransack::Helpers::FormBuilder to
103
118
  construct much more complex search forms, such as the one on the
@@ -109,48 +124,54 @@ You can easily use Ransack to search in associated objects.
109
124
 
110
125
  Given you have these associations ...
111
126
 
112
- class Employee < ActiveRecord::Base
113
- belongs_to :supervisor
127
+ ```ruby
128
+ class Employee < ActiveRecord::Base
129
+ belongs_to :supervisor
114
130
 
115
- # has attribute last_name:string
116
- end
131
+ # has attribute last_name:string
132
+ end
117
133
 
118
- class Department < ActiveRecord::Base
119
- has_many :supervisors
134
+ class Department < ActiveRecord::Base
135
+ has_many :supervisors
120
136
 
121
- # has attribute title:string
122
- end
137
+ # has attribute title:string
138
+ end
123
139
 
124
- class Supervisor < ActiveRecord::Base
125
- belongs_to :department
126
- has_many :employees
140
+ class Supervisor < ActiveRecord::Base
141
+ belongs_to :department
142
+ has_many :employees
127
143
 
128
- # has attribute last_name:string
129
- end
144
+ # has attribute last_name:string
145
+ end
146
+ ```
130
147
 
131
148
  ... and a controller ...
132
149
 
133
- class SupervisorsController < ApplicationController
134
- def index
135
- @search = Supervisor.search(params[:q])
136
- @supervisors = @search.result(:distinct => true)
137
- end
138
- end
150
+ ```ruby
151
+ class SupervisorsController < ApplicationController
152
+ def index
153
+ @search = Supervisor.search(params[:q])
154
+ @supervisors = @search.result(distinct: true)
155
+ end
156
+ end
157
+ ```
139
158
 
140
159
  ... you might set up your form like this ...
141
160
 
142
- <%= search_form_for @search do |f| %>
143
- <%= f.label :last_name_cont %>
144
- <%= f.text_field :last_name_cont %>
161
+ ```erb
162
+ <%= search_form_for @search do |f| %>
163
+ <%= f.label :last_name_cont %>
164
+ <%= f.text_field :last_name_cont %>
145
165
 
146
- <%= f.label :department_title_cont %>
147
- <%= f.text_field :department_title_cont %>
166
+ <%= f.label :department_title_cont %>
167
+ <%= f.text_field :department_title_cont %>
148
168
 
149
- <%= f.label :employees_last_name_cont %>
150
- <%= f.text_field :employees_last_name_cont %>
169
+ <%= f.label :employees_last_name_cont %>
170
+ <%= f.text_field :employees_last_name_cont %>
151
171
 
152
- <%= f.submit "search" %>
153
- <% end %>
172
+ <%= f.submit "search" %>
173
+ <% end %>
174
+ ```
154
175
 
155
176
 
156
177
  ## Contributions
@@ -7,6 +7,8 @@ when /^3\.0\./
7
7
  require 'ransack/adapters/active_record/3.0/context'
8
8
  when /^3\.1\./
9
9
  require 'ransack/adapters/active_record/3.1/context'
10
+ when /^3\.2\./
11
+ require 'ransack/adapters/active_record/3.2/context'
10
12
  else
11
13
  require 'ransack/adapters/active_record/context'
12
14
  end
@@ -10,17 +10,23 @@ module Ransack
10
10
  # Because the AR::Associations namespace is insane
11
11
  JoinDependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency
12
12
  JoinBase = JoinDependency::JoinBase
13
-
13
+
14
+ # Redefine a few things for ActiveRecord 3.0.
15
+
14
16
  def initialize(object, options = {})
15
17
  super
16
18
  @arel_visitor = Arel::Visitors.visitor_for @engine
17
19
  end
18
20
 
21
+ def relation_for(object)
22
+ object.scoped
23
+ end
24
+
19
25
  def evaluate(search, opts = {})
20
26
  viz = Visitor.new
21
27
  relation = @object.where(viz.accept(search.base))
22
28
  if search.sorts.any?
23
- relation = relation.except(:order).order(viz.accept(search.sorts))
29
+ relation = relation.except(:order).reorder(viz.accept(search.sorts))
24
30
  end
25
31
  opts[:distinct] ? relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
26
32
  end
@@ -48,18 +54,6 @@ module Ransack
48
54
  parent.table
49
55
  end
50
56
 
51
- def klassify(obj)
52
- if Class === obj && ::ActiveRecord::Base > obj
53
- obj
54
- elsif obj.respond_to? :klass
55
- obj.klass
56
- elsif obj.respond_to? :active_record
57
- obj.active_record
58
- else
59
- raise ArgumentError, "Don't know how to klassify #{obj}"
60
- end
61
- end
62
-
63
57
  def type_for(attr)
64
58
  return nil unless attr && attr.valid?
65
59
  klassify(attr.parent).columns_hash[attr.arel_attribute.name.to_s].type
@@ -158,4 +152,4 @@ module Ransack
158
152
  end
159
153
  end
160
154
  end
161
- end
155
+ end
@@ -1,4 +1,5 @@
1
1
  require 'ransack/context'
2
+ require 'ransack/adapters/active_record/compat'
2
3
  require 'polyamorous'
3
4
 
4
5
  module Ransack
@@ -8,17 +9,23 @@ module Ransack
8
9
  # Because the AR::Associations namespace is insane
9
10
  JoinDependency = ::ActiveRecord::Associations::JoinDependency
10
11
  JoinPart = JoinDependency::JoinPart
11
-
12
+
13
+ # Redefine a few things for ActiveRecord 3.1.
14
+
12
15
  def initialize(object, options = {})
13
16
  super
14
17
  @arel_visitor = Arel::Visitors.visitor_for @engine
15
18
  end
16
19
 
20
+ def relation_for(object)
21
+ object.scoped
22
+ end
23
+
17
24
  def evaluate(search, opts = {})
18
25
  viz = Visitor.new
19
26
  relation = @object.where(viz.accept(search.base))
20
27
  if search.sorts.any?
21
- relation = relation.except(:order).order(viz.accept(search.sorts))
28
+ relation = relation.except(:order).reorder(viz.accept(search.sorts))
22
29
  end
23
30
  opts[:distinct] ? relation.select("DISTINCT #{@klass.quoted_table_name}.*") : relation
24
31
  end
@@ -46,18 +53,6 @@ module Ransack
46
53
  parent.table
47
54
  end
48
55
 
49
- def klassify(obj)
50
- if Class === obj && ::ActiveRecord::Base > obj
51
- obj
52
- elsif obj.respond_to? :klass
53
- obj.klass
54
- elsif obj.respond_to? :active_record
55
- obj.active_record
56
- else
57
- raise ArgumentError, "Don't know how to klassify #{obj}"
58
- end
59
- end
60
-
61
56
  def type_for(attr)
62
57
  return nil unless attr && attr.valid?
63
58
  name = attr.arel_attribute.name.to_s
@@ -0,0 +1,44 @@
1
+ require 'ransack/context'
2
+ require 'ransack/adapters/active_record/3.1/context'
3
+ require 'ransack/adapters/active_record/compat'
4
+ require 'polyamorous'
5
+
6
+ module Ransack
7
+ module Adapters
8
+ module ActiveRecord
9
+ class Context < ::Ransack::Context
10
+
11
+ # Redefine a few things for ActiveRecord 3.2.
12
+
13
+ def initialize(object, options = {})
14
+ super
15
+ @arel_visitor = @engine.connection.visitor
16
+ end
17
+
18
+ def relation_for(object)
19
+ object.scoped
20
+ end
21
+
22
+ def type_for(attr)
23
+ return nil unless attr && attr.valid?
24
+ name = attr.arel_attribute.name.to_s
25
+ table = attr.arel_attribute.relation.table_name
26
+
27
+ schema_cache = @engine.connection.schema_cache
28
+ raise "No table named #{table} exists" unless schema_cache.table_exists?(table)
29
+ schema_cache.columns_hash[table][name].type
30
+ end
31
+
32
+ def evaluate(search, opts = {})
33
+ viz = Visitor.new
34
+ relation = @object.where(viz.accept(search.base))
35
+ if search.sorts.any?
36
+ relation = relation.except(:order).reorder(viz.accept(search.sorts))
37
+ end
38
+ opts[:distinct] ? relation.uniq : relation
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,5 @@
1
1
  require 'ransack/context'
2
- require 'ransack/adapters/active_record/3.1/context'
2
+ require 'ransack/adapters/active_record/3.2/context'
3
3
  require 'ransack/adapters/active_record/compat'
4
4
  require 'polyamorous'
5
5
 
@@ -8,33 +8,35 @@ module Ransack
8
8
  module ActiveRecord
9
9
  class Context < ::Ransack::Context
10
10
 
11
- # Redefine a few things that have changed with 3.2.
12
-
13
11
  def initialize(object, options = {})
14
12
  super
15
13
  @arel_visitor = @engine.connection.visitor
16
14
  end
17
15
 
16
+ def relation_for(object)
17
+ object.all
18
+ end
19
+
18
20
  def type_for(attr)
19
21
  return nil unless attr && attr.valid?
20
22
  name = attr.arel_attribute.name.to_s
21
23
  table = attr.arel_attribute.relation.table_name
22
24
 
23
- schema_cache = @engine.connection.schema_cache
24
- raise "No table named #{table} exists" unless schema_cache.table_exists?(table)
25
- schema_cache.columns_hash[table][name].type
25
+ schema_cache = @engine.connection.schema_cache
26
+ raise "No table named #{table} exists" unless schema_cache.table_exists?(table)
27
+ schema_cache.columns_hash(table)[name].type
26
28
  end
27
29
 
28
30
  def evaluate(search, opts = {})
29
31
  viz = Visitor.new
30
32
  relation = @object.where(viz.accept(search.base))
31
33
  if search.sorts.any?
32
- relation = relation.except(:order).order(viz.accept(search.sorts))
34
+ relation = relation.except(:order).reorder(viz.accept(search.sorts))
33
35
  end
34
- opts[:distinct] ? relation.uniq : relation
36
+ opts[:distinct] ? relation.distinct : relation
35
37
  end
36
38
 
37
39
  end
38
40
  end
39
41
  end
40
- end
42
+ end