missile_emitter 0.2.0 → 0.3.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.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
|