cast_about_for 0.1.2 → 0.2.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.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/README.md +133 -0
- data/lib/cast_about_for/base.rb +4 -8
- data/lib/cast_about_for/search.rb +59 -0
- data/lib/cast_about_for/validate_macro.rb +69 -0
- data/lib/cast_about_for/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5f49b9f0d9074c8dabf2932029de383179fb429
|
4
|
+
data.tar.gz: 1264283111f24c0fcad5d3e36576644dc1a5eaed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 792179f701b91f51f0988452666e02c7c113839c74edd1a77af90b3a89b64c1bfcf5ffbd6db68ddba7072847e67fa3e0fba4fbf853c635d2692284412f554200
|
7
|
+
data.tar.gz: 20d77f0ac8bb4da57d80b61b80e37baa9cf262bcf8d39eebd9dd09e03d74bf4bb9b565a9b6569a368f871988c1428ec5950c43ec8cab05a8dc2f582f08491f72
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -231,6 +231,139 @@ class Product < ActiveRecord::Base
|
|
231
231
|
# ...
|
232
232
|
end
|
233
233
|
```
|
234
|
+
|
235
|
+
### Comparison
|
236
|
+
If you want to compare a column, the sql like this: The SQL: `SELECT "products".* FROM "products" WHERE (weight >= '100' AND weight <= '1000')`
|
237
|
+
you can do it like this:
|
238
|
+
```ruby
|
239
|
+
# params = {weight_min: 100, weight_max: 1000}
|
240
|
+
# Product.cast_about_for(params)
|
241
|
+
|
242
|
+
class Product < ActiveRecord::Base
|
243
|
+
cast_about_for_params comparison: [{"weight >= ?" => "weight_min"}, {"weight <= ?" => "weight_max"}]
|
244
|
+
|
245
|
+
end
|
246
|
+
```
|
247
|
+
|
248
|
+
###Includes
|
249
|
+
If you want to `includes` other models, you can do it like this
|
250
|
+
```ruby
|
251
|
+
class Product < ActiveRecord::Base
|
252
|
+
cast_about_for_params includes: [:user, :items]
|
253
|
+
|
254
|
+
#This will make `product` include `user` and `items` automatically
|
255
|
+
#Like: Product.includes(:user, :items)
|
256
|
+
end
|
257
|
+
|
258
|
+
```
|
259
|
+
###Joins
|
260
|
+
|
261
|
+
If you want to join a model you can do it like this:
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
Example 1
|
265
|
+
|
266
|
+
class Product < ActiveRecord::Base
|
267
|
+
cast_about_for_params joins: [{user: [equal: :name]}]
|
268
|
+
|
269
|
+
end
|
270
|
+
|
271
|
+
# params = {name: "user"}
|
272
|
+
# Product.cast_about_for(params)
|
273
|
+
# It will be generates like this: Product.joins(:user).where("users.name = ?", "user")
|
274
|
+
# The sql would like this: `SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" WHERE (users.name = 'user')`
|
275
|
+
|
276
|
+
If you want to query the condition of "LIKE", do it like this
|
277
|
+
|
278
|
+
class Product < ActiveRecord::Base
|
279
|
+
cast_about_for_params joins: [{user: [like: :name]}]
|
280
|
+
|
281
|
+
end
|
282
|
+
Then the sql would be like this: `SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" WHERE (users.name Like 'user')`
|
283
|
+
|
284
|
+
|
285
|
+
--------
|
286
|
+
Example 2
|
287
|
+
If you want to nickname the `name` of the params like:
|
288
|
+
# params = {user_name: "user"}
|
289
|
+
# Product.cast_about_for(params)
|
290
|
+
|
291
|
+
class Product < ActiveRecord::Base
|
292
|
+
cast_about_for_params joins: [{user: [equal: {name: :user_name}]}]
|
293
|
+
|
294
|
+
end
|
295
|
+
|
296
|
+
# Also will generates like this: Product.joins(:user).where("users.name = ?", "user")
|
297
|
+
# The sql would like this: `SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" WHERE (users.name = 'user')`
|
298
|
+
|
299
|
+
--------
|
300
|
+
Example 3
|
301
|
+
If multiple user columns that you want to query, you can do it like this:
|
302
|
+
# params = {name: "user", age: 18}
|
303
|
+
# Product.cast_about_for(params)
|
304
|
+
|
305
|
+
class Product < ActiveRecord::Base
|
306
|
+
cast_about_for_params joins: [{user: [equal: [:name, :age]}]
|
307
|
+
|
308
|
+
end
|
309
|
+
# Also will generates like this: Product.joins(:user).where("users.name = ? AND users.age = ?", "user", "18")
|
310
|
+
# The sql would like this: `SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" WHERE (users.name = 'user' AND users.age = 18)`
|
311
|
+
|
312
|
+
|
313
|
+
If you want to nickname the params:
|
314
|
+
# params = {user_name: "user", user_age: 18}
|
315
|
+
# Product.cast_about_for(params)
|
316
|
+
class Product < ActiveRecord::Base
|
317
|
+
cast_about_for_params joins: [{user: [equal: [{name: :user_name}, {age: :user_age}]}]
|
318
|
+
|
319
|
+
end
|
320
|
+
|
321
|
+
--------
|
322
|
+
Example 4
|
323
|
+
You can use the `equal` and `like` at the same time:
|
324
|
+
class Product < ActiveRecord::Base
|
325
|
+
cast_about_for_params joins: [{user: [equal: :age], [like: :name]}]
|
326
|
+
|
327
|
+
end
|
328
|
+
|
329
|
+
`OR`
|
330
|
+
class Product < ActiveRecord::Base
|
331
|
+
cast_about_for_params joins: [{user: [equal: [:age, :height]], [like: [:name, :roles]]}]
|
332
|
+
|
333
|
+
end
|
334
|
+
|
335
|
+
--------
|
336
|
+
Example 5
|
337
|
+
Nested joins:
|
338
|
+
|
339
|
+
Now, I have `product` `user` `company` models,
|
340
|
+
|
341
|
+
class Product < ActiveRecord::Base
|
342
|
+
belongs_to :user
|
343
|
+
end
|
344
|
+
|
345
|
+
class User < ActiveRecord::Base
|
346
|
+
belongs_to :company
|
347
|
+
has_many :products
|
348
|
+
end
|
349
|
+
|
350
|
+
class Company < ActiveRecord::Base
|
351
|
+
has_many :user
|
352
|
+
end
|
353
|
+
|
354
|
+
I have company `name`, and now I want to query the products through the user who belong to the company, so I can do it like this:
|
355
|
+
|
356
|
+
class Product < ActiveRecord::Base
|
357
|
+
cast_about_for_params joins: [{{user: :company} => [like: {name: :company_name}]}]
|
358
|
+
|
359
|
+
end
|
360
|
+
# params = {company_name: "Teo"}
|
361
|
+
# Product.cast_about_for(params)
|
362
|
+
# The sql would like this: SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" INNER JOIN "companies" ON "companies"."id" = "users"."company_id" WHERE (companies.name LIKE 'Teo')
|
363
|
+
|
364
|
+
```
|
365
|
+
|
366
|
+
|
234
367
|
## Advanced Usage
|
235
368
|
|
236
369
|
### JSON API
|
data/lib/cast_about_for/base.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'cast_about_for/search'
|
2
|
+
require 'cast_about_for/validate_macro'
|
2
3
|
module CastAboutFor
|
3
4
|
module Base
|
4
5
|
extend ActiveSupport::Concern
|
5
6
|
|
6
7
|
module ClassMethods
|
7
8
|
include Search
|
8
|
-
CAST_ABOUT_FOR_KEY = [:equal, :like, :enum, :after, :before]
|
9
|
+
CAST_ABOUT_FOR_KEY = [:equal, :like, :enum, :joins, :includes, :after, :before, :comparison]
|
9
10
|
def cast_about_for_params *args
|
10
11
|
|
11
12
|
options = args.extract_options!.dup
|
@@ -14,14 +15,9 @@ module CastAboutFor
|
|
14
15
|
raise ArgumentError, "Unknown cast_about_for key: '#{key}" unless CAST_ABOUT_FOR_KEY.include?(key)
|
15
16
|
end
|
16
17
|
|
17
|
-
validate_keys = options.slice(*CAST_ABOUT_FOR_KEY.first(
|
18
|
+
validate_keys = options.slice(*CAST_ABOUT_FOR_KEY.first(5))
|
18
19
|
|
19
|
-
|
20
|
-
value.each do |attribute|
|
21
|
-
attribute = attribute.is_a?(Hash) ? attribute.first.first : attribute
|
22
|
-
raise ArgumentError, "Unknown column: #{attribute}" unless self.respond_to?(attribute) || self.column_names.include?(attribute.to_s)
|
23
|
-
end
|
24
|
-
end
|
20
|
+
ValidateMacro.validate(self, validate_keys)
|
25
21
|
|
26
22
|
class_variable_set(:@@cast_about_for_params, options)
|
27
23
|
end
|
@@ -68,6 +68,33 @@ module CastAboutFor
|
|
68
68
|
seach_model
|
69
69
|
end
|
70
70
|
|
71
|
+
def cast_about_for_by_comparison search_values, params, seach_model
|
72
|
+
search_values.each do |comparison|
|
73
|
+
comparison.each do |seach_mod, search_name|
|
74
|
+
seach_model = seach_model.where("#{seach_mod}", params[search_name.to_sym]) if params.present? && params[search_name.to_sym].present?
|
75
|
+
end
|
76
|
+
end
|
77
|
+
seach_model
|
78
|
+
end
|
79
|
+
|
80
|
+
def cast_about_for_by_joins search_values, params, seach_model
|
81
|
+
search_values.each do |associations|
|
82
|
+
associations.each do |association, association_operations|
|
83
|
+
association_operations.each do |operations|
|
84
|
+
operations.each do |action, columns|
|
85
|
+
seach_model = send("#{action.to_s}_operation", association, columns, params, seach_model)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
seach_model
|
91
|
+
end
|
92
|
+
|
93
|
+
def cast_about_for_by_includes search_values, params, seach_model
|
94
|
+
seach_model = seach_model.includes(search_values)
|
95
|
+
seach_model
|
96
|
+
end
|
97
|
+
|
71
98
|
def obtain_value(value)
|
72
99
|
case value
|
73
100
|
when Hash then [value.first.first, value.first.last]
|
@@ -87,5 +114,37 @@ module CastAboutFor
|
|
87
114
|
raise ArgumentError, "Unknown column: #{column}" unless self.respond_to?(column) || self.column_names.include?(column.to_s)
|
88
115
|
[column.to_sym, value[:time]]
|
89
116
|
end
|
117
|
+
|
118
|
+
def like_operation(association, columns, params, seach_model)
|
119
|
+
association, association_name = obtain_joins_value(association)
|
120
|
+
columns = columns.is_a?(Array) ? columns : [columns]
|
121
|
+
columns.each do |column|
|
122
|
+
search_column, search_name = obtain_value(column)
|
123
|
+
seach_model = seach_model.joins(association).where("#{association_name.to_s.pluralize}.#{search_column} LIKE ?", "%#{params[search_name.to_sym]}%") if params.present? && params[search_name.to_sym].present?
|
124
|
+
end
|
125
|
+
p
|
126
|
+
seach_model
|
127
|
+
end
|
128
|
+
|
129
|
+
def equal_operation(association, columns, params, seach_model)
|
130
|
+
association, association_name = obtain_joins_value(association)
|
131
|
+
columns = columns.is_a?(Array) ? columns : [columns]
|
132
|
+
columns.each do |column|
|
133
|
+
search_column, search_name = obtain_value(column)
|
134
|
+
seach_model = seach_model.joins(association).where("#{association_name.to_s.pluralize}.#{search_column} = ?", params[search_name.to_sym]) if params.present? && params[search_name.to_sym].present?
|
135
|
+
end
|
136
|
+
seach_model
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
def obtain_joins_value(value)
|
141
|
+
if Hash === value #如果是hash则使用嵌入式joins
|
142
|
+
association = {}
|
143
|
+
value.each{|k, v| association[k.to_sym] = v.to_sym}
|
144
|
+
[association, value.flatten.last]
|
145
|
+
else
|
146
|
+
[value.to_sym, value]
|
147
|
+
end
|
148
|
+
end
|
90
149
|
end
|
91
150
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module CastAboutFor
|
2
|
+
module ValidateMacro
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def validate(record, options)
|
7
|
+
options.each do |key, value|
|
8
|
+
case key
|
9
|
+
when :joins then send("validate_join", record, value)
|
10
|
+
when :includes then send("validate_includes", record, value)
|
11
|
+
else send("validate_others", record, value)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def validate_join(record, value)
|
19
|
+
value.each do |association|
|
20
|
+
association.each do |association_name, association_operations|
|
21
|
+
validate_join_associations(record, association_name)
|
22
|
+
|
23
|
+
association_operations.each do |operations|
|
24
|
+
operations.each_value do |columns|
|
25
|
+
association_name = association_name.is_a?(Hash) ? association_name.flatten.last : association_name
|
26
|
+
klass = Object.const_get("#{association_name}".camelize.singularize)
|
27
|
+
columns = columns.is_a?(Array) ? columns : [columns]
|
28
|
+
columns.each do |column|
|
29
|
+
column = column.is_a?(Hash) ? column.first.first : column
|
30
|
+
raise ArgumentError, "Unknown column: #{column} for #{klass}" unless klass.column_names.include?("#{column}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate_includes(record, value)
|
39
|
+
value = value.is_a?(Array) ? value : [value]
|
40
|
+
value.each do |association|
|
41
|
+
raise ArgumentError, "Unknown association #{association} fo #{record}" unless record._reflections.keys.include?(association.to_s)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def validate_others(record, value)
|
46
|
+
value.each do |attribute|
|
47
|
+
attribute = attribute.is_a?(Hash) ? attribute.first.first : attribute
|
48
|
+
raise ArgumentError, "Unknown column: #{attribute} fo #{record}" unless record.respond_to?(attribute) || record.column_names.include?(attribute.to_s)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def validate_join_associations(record, association_name)
|
53
|
+
if association_name.is_a?(Hash) #检查是否为嵌入式的joins,例如: A.joins(b: :c)
|
54
|
+
association_name.each do |key, value|
|
55
|
+
validate_join_association(record, key)
|
56
|
+
validate_join_association(Object.const_get("#{key}".camelize.singularize), value)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
validate_join_association(record, association_name)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def validate_join_association(record, association_name)
|
64
|
+
# _reflections method come from rails ActiveRecord::Reflection
|
65
|
+
raise ArgumentError, "Unknown association #{association_name} fo #{record}" unless record._reflections.keys.include?(association_name.to_s)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cast_about_for
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- JeskTop
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -156,6 +156,7 @@ files:
|
|
156
156
|
- lib/cast_about_for.rb
|
157
157
|
- lib/cast_about_for/base.rb
|
158
158
|
- lib/cast_about_for/search.rb
|
159
|
+
- lib/cast_about_for/validate_macro.rb
|
159
160
|
- lib/cast_about_for/version.rb
|
160
161
|
homepage: https://github.com/minnowlab/cast_about_for/
|
161
162
|
licenses:
|