cast_about_for 0.1.2 → 0.2.0

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: f89b80544593269d2556df48a28845c7b9afb875
4
- data.tar.gz: f32a8afe8c775646c101a17976ff144d43d43076
3
+ metadata.gz: e5f49b9f0d9074c8dabf2932029de383179fb429
4
+ data.tar.gz: 1264283111f24c0fcad5d3e36576644dc1a5eaed
5
5
  SHA512:
6
- metadata.gz: c1ee3ad830d4fa24b31b4f45c000561120c72059b0945741909aa3e980ae952005f593eadea3ee95d2ce734387d88e63e8b6fff9b5cb9811302b10d6e84d3441
7
- data.tar.gz: 071d92105a788ec87ba1a930dd42c88962637a2feea7ad956e2b018ac02569288687d94abb2b4e9236519da367ab877d756c87fdfa5782ae35a7059c29f652f9
6
+ metadata.gz: 792179f701b91f51f0988452666e02c7c113839c74edd1a77af90b3a89b64c1bfcf5ffbd6db68ddba7072847e67fa3e0fba4fbf853c635d2692284412f554200
7
+ data.tar.gz: 20d77f0ac8bb4da57d80b61b80e37baa9cf262bcf8d39eebd9dd09e03d74bf4bb9b565a9b6569a368f871988c1428ec5950c43ec8cab05a8dc2f582f08491f72
data/Gemfile CHANGED
@@ -3,6 +3,6 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in cast_about_for.gemspec
4
4
  gemspec
5
5
 
6
- gem 'activerecord', '5.0.0'
7
- gem 'sqlite3'
6
+ gem 'activerecord', '~> 5.0.0.1'
7
+ gem 'sqlite3', '~> 1.3.11'
8
8
  gem 'minitest'
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
@@ -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(3))
18
+ validate_keys = options.slice(*CAST_ABOUT_FOR_KEY.first(5))
18
19
 
19
- validate_keys.each do |key, value|
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
@@ -1,3 +1,3 @@
1
1
  module CastAboutFor
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  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.1.2
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-09-22 00:00:00.000000000 Z
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: