advanced 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 724d8cb29889df2f6de2afe41f73cb9e561e1289
4
- data.tar.gz: 48c4f5887dcf0bdf1c6f283f83f00563bb44c549
3
+ metadata.gz: 53d443c5de56e2d0a6ea9cca3c9fc004b7abb5bd
4
+ data.tar.gz: 19f45cb819603d9aae9481310ff15d8738cfca50
5
5
  SHA512:
6
- metadata.gz: 5725b13768e2bf2f4fa7adbfb3c940709de00a0968fd66f7552a3804db63f0f9ee64531b9bd647d8f5cef3d79d6fa1cb7c453aab8ba0904e22c8fc430705bb32
7
- data.tar.gz: 134cbb8a9e80be41ae76ce7c88dd33b4cf816e94bd11fdc2c8f96347a0c7e2ed5d7b215906bb8f56e0522366ff2ef68d1eabe9667bf0097fa948748bc65a7db5
6
+ metadata.gz: 3b2ef8b08fa42d2b7e3349003fef96f764f2ef28a194bb66b7d161b3721a09dceabbf658ce5f3c35ab681738443983074fb85a92f2e2e9bbb493e0749d8e279d
7
+ data.tar.gz: 50923019d6fa927fcfa10eeba8837f09a5b7968db7228ce7ee0bf8251a515059a292d75409cc8a8d19301bb9d0e8b70bf2ed0b203d55cfe9424815c2e695963b
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Advanced
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/advanced`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Advanced is a library for building complex searches with Active Record.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ [Click here to see the source for the demo application.](https://github.com/rzane/advanced_demo)
6
6
 
7
7
  ## Installation
8
8
 
@@ -22,19 +22,192 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ ### Advanced::Search
26
26
 
27
- ## Development
27
+ Start by inheriting Advanced::Search.
28
28
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
29
+ ```ruby
30
+ class StateSearch < Advanced::Search
31
+ def search_name(name:, **)
32
+ where('states.name like ?', "%#{name}%")
33
+ end
34
+ end
35
+ ```
36
+
37
+ `Advanced::Search` will look at the methods you've defined that start with `search_`. Above, we've declared the `search_name` method and listed the `name` parameter as a required key.
38
+
39
+ ```ruby
40
+ StateSearch.call(State.all, name: 'New')
41
+ #=> SELECT * FROM states WHERE states.name like '%New%'
42
+
43
+ StateSearch.call(State.all, foo: 'bar')
44
+ #=> SELECT * FROM states
45
+
46
+ StateSearch.call(State.all, name: '')
47
+ #=> SELECT * FROM states
48
+ ```
49
+
50
+ ### Search composition
51
+
52
+ We can compose multiple search objects.
53
+
54
+ ```ruby
55
+ class CitySearch < Advanced::Search
56
+ def search_name(name:, **)
57
+ where('cities.name like ?', "%#{name}%")
58
+ end
59
+
60
+ def search_state(state:, **)
61
+ joins(:state).merge StateSearch.call(State.all, state)
62
+ end
63
+ end
64
+ ```
65
+
66
+ ```ruby
67
+ CitySearch.call(City.all, name: 'New York')
68
+ #=> SELECT "cities".* FROM "cities" WHERE (cities.name like '%New York%')
69
+
70
+ CitySearch.call(City.all, state: { name: 'New York' })
71
+ #=> SELECT "cities".* FROM "cities"
72
+ #=> INNER JOIN "states" ON "states"."id" = "cities"."state_id"
73
+ #=> WHERE (states.name like '%New York%')
74
+ ```
75
+
76
+ ### Advanced::SearchForm
77
+
78
+ A common feature in Rails applications is building filters. `Advanced::SearchForm` can help you do that. It's basically just a hash that is compatible with Rails form builders.
79
+
80
+ ```ruby
81
+ class StateSearch < Advanced::Search
82
+ # ...
83
+
84
+ class Form < Advanced::SearchForm
85
+ search StateSearch
86
+ end
87
+ end
88
+ ```
89
+
90
+ It scans the keyword arguments in your search methods and defines accessors automatically:
91
+
92
+ ```ruby
93
+ form = StateSearch::Form.new(name: 'Foo')
94
+ form.name #=> 'Foo'
95
+ form.name = 'Bar'
96
+ form.name #=> 'Bar'
97
+ form.to_h #=> { name: 'Foo' }
98
+ ```
99
+
100
+ `Advanced::Search` treats this object like a hash, so you can just pass it along:
101
+
102
+ ```ruby
103
+ StateSearch.call(State.all, form)
104
+ ```
30
105
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
106
+ So, a controller action might look like this:
107
+
108
+ ```ruby
109
+ def index
110
+ @form = StateSearch::Form.new(params[:q])
111
+ @states = StateSearch.call(State.all, @form)
112
+ end
113
+ ```
114
+
115
+ Your view might look something like this:
116
+
117
+ ```erb
118
+ <%= form_for @form, method: :get, url: states_path, as: :q do |f| %>
119
+ <p>
120
+ <%= f.label :name %>
121
+ <%= f.text_field :name %>
122
+ </p>
123
+
124
+ <%= f.submit 'Search' %>
125
+ <% end %>
126
+
127
+ <table>
128
+ <thead>
129
+ <tr>
130
+ <th>Name</th>
131
+ </tr>
132
+ </thead>
133
+
134
+ <tbody>
135
+ <% @states.each do |state| %>
136
+ <tr>
137
+ <td><%= state.name %></td>
138
+ </tr>
139
+ <% end %>
140
+ </tbody>
141
+ </table>
142
+ ```
143
+
144
+ ### Composing forms
145
+
146
+ You can compose forms just like your compose your searches.
147
+
148
+ ```ruby
149
+ class CitySearch < Advanced::Search
150
+ # ...
151
+ class Form < Advanced::SearchForm
152
+ search CitySearch
153
+ nested :state, StateSearch::Form
154
+ end
155
+ end
156
+ ```
157
+
158
+ ```ruby
159
+ form = CitySearch::Form.new(name: 'New York', state: { name: 'New York' })
160
+ form.name #=> 'New York'
161
+ form.state.name #=> 'New York'
162
+ form.to_h #=> { name: 'New York', state: { name: 'New York' }}
163
+ ```
164
+
165
+ Then, in your view, you can use `fields_for` to generate your form fields:
166
+
167
+ ```ruby
168
+ <%= form_for @form, method: :get, url: cities_path, as: :q do |f| %>
169
+ <p>
170
+ <%= f.label :name %>
171
+ <%= f.text_field :name %>
172
+ </p>
173
+
174
+ <%= f.fields_for :state do |state| %>
175
+ <p>
176
+ <%= state.label :name, 'State' %>
177
+ <%= state.text_field :name %>
178
+ </p>
179
+ <% end %>
180
+
181
+ <%= f.submit 'Search' %>
182
+ <% end %>
183
+ ```
184
+
185
+ # Other goodies
186
+
187
+ You can extend your models with a search method to keep it brief.
188
+
189
+ ```ruby
190
+ class State < ApplicationRecord
191
+ extend StateSearch.scope
192
+ end
193
+ ```
194
+
195
+ Now, you have a shorthand:
196
+
197
+ ```ruby
198
+ State.search(name: 'New York')
199
+ ```
200
+
201
+ If you'd prefer to call your search method something other than `search`, that's cool too:
202
+
203
+ ```ruby
204
+ extend StateSearch.scope(:custom_search)
205
+ ```
32
206
 
33
207
  ## Contributing
34
208
 
35
209
  Bug reports and pull requests are welcome on GitHub at https://github.com/Ray Zane/advanced.
36
210
 
37
-
38
211
  ## License
39
212
 
40
213
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -34,10 +34,8 @@ module Advanced
34
34
  instance_variable_set(ivar, form.new)
35
35
  end
36
36
 
37
- ["#{key}=", "#{key}_attributes="].each do |name|
38
- define_method(name) do |values|
39
- instance_variable_set(ivar, form.new(values))
40
- end
37
+ define_method("#{key}=") do |values|
38
+ instance_variable_set(ivar, form.new(values))
41
39
  end
42
40
  end
43
41
 
@@ -1,3 +1,3 @@
1
1
  module Advanced
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: advanced
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ray Zane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-09 00:00:00.000000000 Z
11
+ date: 2017-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport