Skip to content

Commit 890c715

Browse files
committed
parse rails model associations
1 parent fe87d54 commit 890c715

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

lib/helpers/parse_rails.rb

+47
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,52 @@
3030
# }
3131
# }
3232
save_data(:rails_tables, tables)
33+
34+
associations = []
35+
context_stack = []
36+
37+
within_files Synvert::RAILS_MODEL_FILES do
38+
add_callback :module_node, at: 'start' do |node|
39+
name = node.constant_path.to_source
40+
context_stack.push(name)
41+
end
42+
43+
add_callback :module_node, at: 'end' do |node|
44+
context_stack.pop
45+
end
46+
47+
add_callback :class_node, at: 'start' do |node|
48+
name = node.constant_path.to_source
49+
context_stack.push(name)
50+
end
51+
52+
add_callback :class_node, at: 'end' do |node|
53+
context_stack.pop
54+
end
55+
56+
add_callback :call_node, at: 'start' do |node|
57+
if node.receiver.nil? && %i[belongs_to has_one has_many has_and_belongs_to_many].include?(node.name)
58+
association_name = node.arguments.arguments.first.to_value
59+
option_elements = node.arguments.arguments.second&.elements
60+
options = {}
61+
if option_elements
62+
%i[foreign_key foreign_type polymorphic].each do |option_key|
63+
option_element = option_elements.find { |element| element.key.value == option_key.to_s }
64+
options[option_key] = option_element.value.to_value if option_element
65+
end
66+
end
67+
associations << { class_name: context_stack.join('::'), name: association_name.to_s, type: node.name.to_s, **options }
68+
end
69+
end
70+
end
71+
# rails_models
72+
# {
73+
# associations: [
74+
# { class_name: "Polymorphic", name: "imageable", type: "belongs_to", polymorphic: true }
75+
# { class_name: "User", name: "organization", type: "belongs_to" },
76+
# { class_name: "User", name: "posts", type: "has_many" }
77+
# ]
78+
# }
79+
save_data(:rails_models, associations: associations)
3380
end
3481
end

spec/helpers/parse_rails_spec.rb

+30
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,34 @@
4343
}
4444
})
4545
end
46+
47+
it 'saves associations' do
48+
rewriter =
49+
Synvert::Rewriter.new 'test', 'rails_parse_helper' do
50+
call_helper 'rails/parse'
51+
end
52+
53+
FileUtils.mkdir_p('app/models')
54+
File.write('app/models/user.rb', <<~EOF)
55+
class User < ApplicationRecord
56+
belongs_to :organization
57+
has_many :posts, dependent: :destroy
58+
end
59+
EOF
60+
File.write('app/models/picture.rb', <<~EOF)
61+
class Picture < ApplicationRecord
62+
belongs_to :imageable, polymorphic: true
63+
end
64+
EOF
65+
66+
rewriter.process
67+
68+
expect(rewriter.load_data(:rails_models)).to eq({
69+
associations: [
70+
{ class_name: "Picture", name: "imageable", type: "belongs_to", polymorphic: true },
71+
{ class_name: "User", name: "organization", type: "belongs_to" },
72+
{ class_name: "User", name: "posts", type: "has_many" }
73+
]
74+
})
75+
end
4676
end

0 commit comments

Comments
 (0)