-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathconvert_model_lambda_scope.rb
111 lines (100 loc) · 3.75 KB
/
convert_model_lambda_scope.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# frozen_string_literal: true
Synvert::Rewriter.new 'rails', 'convert_model_lambda_scope' do
configure(parser: Synvert::PRISM_PARSER)
description <<~EOS
It converts activerecord scope to lambda scope.
```ruby
class Post < ActiveRecord::Base
scope :active, where(active: true)
scope :published, Proc.new { where(published: true) }
scope :by_user, proc { |user_id| where(user_id: user_id) }
default_scope order("updated_at DESC")
default_scope { order("created_at DESC") }
end
```
=>
```ruby
class Post < ActiveRecord::Base
scope :active, -> { where(active: true) }
scope :published, -> { where(published: true) }
scope :by_user, ->(user_id) { where(user_id: user_id) }
default_scope -> { order("updated_at DESC") }
default_scope -> { order("created_at DESC") }
end
```
EOS
if_gem 'activerecord', '>= 4.0'
within_files Synvert::RAILS_MODEL_FILES do
# scope :active, where(active: true) => scope :active, -> { where(active: true) }
with_node node_type: 'call_node',
receiver: nil,
name: 'scope',
arguments: {
node_type: 'arguments_node',
arguments: {
size: 2,
last: {
node_type: 'call_node',
name: { not_in: ['new', 'proc', 'lambda'] }
}
}
} do
goto_node 'arguments.arguments.last' do
wrap prefix: '-> { ', suffix: ' }'
end
end
with_node node_type: 'call_node',
receiver: nil,
name: 'scope',
arguments: {
node_type: 'arguments_node',
arguments: {
size: 2,
last: {
node_type: 'call_node',
receiver: 'Proc',
name: 'new'
}
}
} do
if node.arguments.arguments.last.block.parameters
replace 'arguments.arguments.last',
with: '->({{arguments.arguments.last.block.parameters.parameters}}) { {{arguments.arguments.last.block.body}} }'
else
replace 'arguments.arguments.last', with: '-> { {{arguments.arguments.last.block.body}} }'
end
end
with_node node_type: 'call_node',
receiver: nil,
name: 'scope',
arguments: {
node_type: 'arguments_node',
arguments: {
size: 2,
last: {
node_type: 'call_node',
receiver: nil,
name: { in: ['proc', 'lambda'] }
}
}
} do
if node.arguments.arguments.last.block.parameters
replace 'arguments.arguments.last',
with: '->({{arguments.arguments.last.block.parameters.parameters}}) { {{arguments.arguments.last.block.body}} }'
else
replace 'arguments.arguments.last', with: '-> { {{arguments.arguments.last.block.body}} }'
end
end
# default_scope order("updated_at DESC") => default_scope -> { order("updated_at DESC") }
with_node node_type: 'call_node',
receiver: nil,
name: 'default_scope',
arguments: { node_type: 'arguments_node', arguments: { size: 1, first: { node_type: 'call_node' } } } do
replace_with 'default_scope -> { {{arguments.arguments.first}} }'
end
# default_scope { order("updated_at DESC") } => default_scope -> { order("updated_at DESC") }
with_node node_type: 'call_node', receiver: nil, name: 'default_scope', block: { node_type: 'block_node' } do
replace_with 'default_scope -> { {{block.body.body}} }'
end
end
end