missile_emitter 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +13 -16
- data/lib/missile_emitter.rb +5 -4
- data/lib/missile_emitter/attributes.rb +18 -0
- data/lib/missile_emitter/battle_field.rb +3 -3
- data/lib/missile_emitter/searchable.rb +34 -0
- data/lib/missile_emitter/version.rb +1 -1
- data/missile_emitter.gemspec +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f86e582ded328222839a9d72ee7acbd580e90bd1d98ac46da80c2a4a1cd5582
|
4
|
+
data.tar.gz: 609969e33ce1b457879f1a45396c378d116f39f06e29b482d28f69970ae716de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 167addbf7b4fae490309320664467c40153973d6ec4d7b5b440452b9dd8547db1f15eca2a9716b8921630d518a8bdf5ca60de9d7daf611f8265fa8f6db538bda
|
7
|
+
data.tar.gz: eff5ffb62d6885be78f20bc7950321d307ccd038588d0f14cebc6e42ec17872f90225923c9847dd807290815dc2d85dfc92dc462fdcab111e7a86a2116f3e923
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -102,13 +102,12 @@ me.age # => 36
|
|
102
102
|
|
103
103
|
```ruby
|
104
104
|
module Searchable
|
105
|
-
# 搜索条件(klass => {
|
106
|
-
# eg. {Person => {name_like:
|
107
|
-
conditions = {}
|
105
|
+
# 搜索条件(klass => {field: scope})
|
106
|
+
# eg. {Person => {name_like: scope, older_than: scope}}
|
107
|
+
conditions = {}
|
108
108
|
|
109
109
|
MissileEmitter do |klass, key, *, &block|
|
110
|
-
conditions[klass] ||= {}
|
111
|
-
conditions[klass][key] = block
|
110
|
+
(conditions[klass] ||= {}.with_indifferent_access)[key] = block
|
112
111
|
end
|
113
112
|
|
114
113
|
extend ActiveSupport::Concern
|
@@ -117,15 +116,13 @@ module Searchable
|
|
117
116
|
|
118
117
|
define_singleton_method :search do |hash|
|
119
118
|
hash.reduce all do |relation, (key, value)|
|
120
|
-
#
|
121
|
-
relation = relation.extending do
|
122
|
-
define_method(:_) { value }
|
123
|
-
end
|
119
|
+
next relation if value.blank? # ignore empty value
|
124
120
|
|
125
|
-
if
|
126
|
-
relation
|
127
|
-
|
128
|
-
|
121
|
+
if filter = conditions.fetch(self, {})[key]
|
122
|
+
relation.extending do
|
123
|
+
# Just for fun :)
|
124
|
+
define_method(:_) { value }
|
125
|
+
end.instance_exec(value, &filter)
|
129
126
|
elsif column_names.include?(key)
|
130
127
|
relation.where key => value
|
131
128
|
else
|
@@ -151,12 +148,12 @@ end
|
|
151
148
|
最后,在业务代码中使用:
|
152
149
|
|
153
150
|
```ruby
|
154
|
-
# params: {name: 'Jerry', older_than: 18}
|
151
|
+
# params: {name: 'Jerry', older_than: 18, sex: 'male'}
|
155
152
|
Person.search params.slice(:name_like, :older_than, :sex)
|
156
|
-
#
|
153
|
+
# 参数值不为空的情况下,等价于:
|
157
154
|
Person.where('name like ?', "%#{params[:name_like]}%")
|
158
155
|
.where('age >= ?', params[:older_than])
|
159
156
|
.where(sex: params[:sex])
|
160
157
|
```
|
161
158
|
|
162
|
-
|
159
|
+
总而言之,使用导弹发射器,可以方便的在类定义级别实现声明式DSL(示例参见 [`attributes.rb`](https://github.com/coding-class-club/missile_emitter/blob/master/lib/missile_emitter/attributes.rb) 、[`searchable.rb`](https://github.com/coding-class-club/missile_emitter/blob/master/lib/missile_emitter/searchable.rb)),至于更多的用法,就留给你自己慢慢挖掘啦。
|
data/lib/missile_emitter.rb
CHANGED
@@ -18,7 +18,7 @@ module MissileEmitter
|
|
18
18
|
def exec(namespace, &block)
|
19
19
|
raise Error.new("需要提供代码块") unless block_given?
|
20
20
|
|
21
|
-
context = block.binding.
|
21
|
+
context = block.binding.receiver
|
22
22
|
|
23
23
|
raise Error.new("只能再具名模块中调用") unless context.instance_of?(Module) && context.name
|
24
24
|
|
@@ -39,10 +39,10 @@ module MissileEmitter
|
|
39
39
|
container = !ns.empty? && namespace ? constantize(ns) : Kernel
|
40
40
|
action = container == Kernel ? 'define_method' : 'define_singleton_method'
|
41
41
|
|
42
|
-
container.send action, name do
|
43
|
-
klass = missile.binding.
|
42
|
+
container.send action, name do |*args, &missile|
|
43
|
+
klass = missile.binding.receiver
|
44
44
|
battle_field = BattleField.new klass, MissileEmitter.mapping[context]
|
45
|
-
battle_field.emit! &missile
|
45
|
+
battle_field.emit! *args, &missile
|
46
46
|
|
47
47
|
context
|
48
48
|
end
|
@@ -87,6 +87,7 @@ module MissileEmitter
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
90
|
+
|
90
91
|
end
|
91
92
|
|
92
93
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module MissileEmitter
|
2
|
+
module Attributes
|
3
|
+
MissileEmitter do |klass, field, default, *, &block|
|
4
|
+
attribute = "@#{field}" # 构造实例变量名称,如:name => @name
|
5
|
+
# 动态定义实例⽅法
|
6
|
+
klass.define_method field do
|
7
|
+
if instance_variable_defined?(attribute)
|
8
|
+
instance_variable_get attribute
|
9
|
+
else
|
10
|
+
#返回声明的默认值,同样考虑传递Proc的情况
|
11
|
+
block ? instance_eval(&block) : default
|
12
|
+
end
|
13
|
+
end
|
14
|
+
# 写值⽅法
|
15
|
+
attr_writer field
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module MissileEmitter
|
2
2
|
class BattleField < BasicObject
|
3
3
|
|
4
|
-
def initialize(context, callable)
|
5
|
-
@context, @handler = context, callable
|
4
|
+
def initialize(context, *extras, callable)
|
5
|
+
@context, @extras, @handler = context, extras, callable
|
6
6
|
end
|
7
7
|
|
8
8
|
def method_missing(*args, &block)
|
9
|
-
@handler.call @context, *args, &block
|
9
|
+
@handler.call @context, *@extras, *args, &block
|
10
10
|
end
|
11
11
|
|
12
12
|
alias_method :emit!, :instance_eval
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module MissileEmitter
|
2
|
+
module Searchable
|
3
|
+
|
4
|
+
# 搜索条件(klass => {field: scope})
|
5
|
+
# eg. {Person => {name_like: scope, older_than: scope}}
|
6
|
+
conditions = {}
|
7
|
+
|
8
|
+
MissileEmitter do |klass, key, *, &block|
|
9
|
+
(conditions[klass] ||= {}.with_indifferent_access)[key] = block
|
10
|
+
end
|
11
|
+
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
included do
|
15
|
+
|
16
|
+
define_singleton_method :search do |hash|
|
17
|
+
hash.reduce all do |relation, (key, value)|
|
18
|
+
next relation if value.blank? # ignore empty value
|
19
|
+
|
20
|
+
if filter = conditions.fetch(self, {})[key]
|
21
|
+
relation.extending do
|
22
|
+
# Just for fun :)
|
23
|
+
define_method(:_) { value }
|
24
|
+
end.instance_exec(value, &filter)
|
25
|
+
elsif column_names.include?(key)
|
26
|
+
relation.where key => value
|
27
|
+
else
|
28
|
+
relation
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/missile_emitter.gemspec
CHANGED
@@ -5,7 +5,7 @@ require "missile_emitter/version"
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "missile_emitter"
|
7
7
|
spec.version = MissileEmitter::VERSION
|
8
|
-
spec.authors = ["
|
8
|
+
spec.authors = ["Jerry Chen"]
|
9
9
|
spec.email = ["code@coding-class.com"]
|
10
10
|
|
11
11
|
spec.summary = %q{Ruby元编程辅助工具}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: missile_emitter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Jerry Chen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,7 +86,9 @@ files:
|
|
86
86
|
- bin/console
|
87
87
|
- bin/setup
|
88
88
|
- lib/missile_emitter.rb
|
89
|
+
- lib/missile_emitter/attributes.rb
|
89
90
|
- lib/missile_emitter/battle_field.rb
|
91
|
+
- lib/missile_emitter/searchable.rb
|
90
92
|
- lib/missile_emitter/version.rb
|
91
93
|
- missile_emitter.gemspec
|
92
94
|
homepage: https://github.com/coding-class-club/missile_emitter
|