Skip to content

Commit

Permalink
feat: Add support for removed, renamed and ignored columns (#49)
Browse files Browse the repository at this point in the history
* ci: Update .deepsource.toml

* ignore columns

* rename and remove fields

* fix rename field type

* first minor version

* ignore columns defined as string

---------

Co-authored-by: deepsource-totalanarchy[bot] <107136100+deepsource-totalanarchy[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 94c2393 commit b6d44ab
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 6 deletions.
9 changes: 8 additions & 1 deletion lib/trains/dto/model.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
module Trains
module DTO
Model = Data.define(:name, :fields, :version)
Model = Data.define(
:name, :fields, :version, :renamed_columns, :removed_columns, :ignored_columns
) do
def initialize(name:, fields:, version:, renamed_columns: [],
removed_columns: [], ignored_columns: [])
super(name:, fields:, version:, renamed_columns:, removed_columns:, ignored_columns:)
end
end
end
end
5 changes: 5 additions & 0 deletions lib/trains/dto/rename.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Trains
module DTO
Rename = Data.define(:from, :to)
end
end
16 changes: 15 additions & 1 deletion lib/trains/utils/migration_tailor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ def self.stitch(models = {}, migrations)
end
when :add_column, :add_column_with_default, :add_reference
models[mig.table_name].fields.push(*mig.fields)
when :ignore_column
models[mig.table_name].ignored_columns.push(*mig.fields.map(&:name))
when :remove_column
column =
models[mig.table_name].fields.find do |field|
field.name == mig.fields.first.name
end
models[mig.table_name].fields.delete(column)
models[mig.table_name].removed_columns.push(mig.fields.first.name)
when :rename_column
column =
models[mig.table_name].fields.find do |field|
Expand All @@ -37,6 +40,11 @@ def self.stitch(models = {}, migrations)
)
)
models[mig.table_name].fields.delete(column)
models[mig.table_name].renamed_columns.push(
Trains::DTO::Rename.new(
from: mig.fields.first.name.to_sym, to: mig.fields.first.type.to_sym
)
)
when :change_table
mig.fields.each do |field|
case field.type
Expand All @@ -46,6 +54,7 @@ def self.stitch(models = {}, migrations)
mod_field.name == field.name
end
models[mig.table_name].fields.delete(column)
models[mig.table_name].removed_columns.push(field.name)
when :rename
# find the field and store temporarily
column =
Expand All @@ -55,12 +64,17 @@ def self.stitch(models = {}, migrations)
# Create new field from temp with new name
models[mig.table_name].fields.push(
Trains::DTO::Field.new(
name: field.name[1],
name: field.name[1].to_sym,
type: column.type
)
)
# Delete the field
models[mig.table_name].fields.delete(column)
models[mig.table_name].renamed_columns.push(
Trains::DTO::Rename.new(
from: field.name[0], to: field.name[1]
)
)
else
models[mig.table_name].fields.push(field)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/trains/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Trains
VERSION = '0.0.19'.freeze
VERSION = '0.1.0'.freeze
end
20 changes: 20 additions & 0 deletions lib/trains/visitor/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Model < Base
belongs_to
has_one
has_and_belongs_to_many
ignored_columns=
].freeze
MODEL_PARENT_CLASSES = %w[
ApplicationRecord
Expand All @@ -32,6 +33,25 @@ def on_class(node)
def parse_model(node)
return unless POSSIBLE_ASSOCIATIONS.include?(node.method_name)

if node.method_name == :ignored_columns=
return if node.arguments.nil?
return unless node.arguments.first.is_a? RuboCop::AST::ArrayNode

arguments = node.arguments.first.to_a
arguments = arguments.select do |child|
child.is_a?(RuboCop::AST::SymbolNode) || child.is_a?(RuboCop::AST::StrNode)
end.map(&:value)

@result << DTO::Migration.new(
@model_class,
:ignore_column,
[*arguments.map { |arg| DTO::Field.new(arg.to_sym, nil) }],
nil
)

return
end

@result << DTO::Migration.new(
@model_class,
:add_column,
Expand Down
11 changes: 9 additions & 2 deletions spec/lib/trains/utils/migration_tailor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@
fields: [
Trains::DTO::Field.new(:more, :text)
],
version: 5.2
version: 5.2,
removed_columns: [:title]
)
}
)
Expand Down Expand Up @@ -201,7 +202,13 @@
Trains::DTO::Field.new(:updated_at, :datetime),
Trains::DTO::Field.new(:alive_since, :integer),
Trains::DTO::Field.new(:name, :string)
]
],
renamed_columns: [
Trains::DTO::Rename.new(:name, :whatup),
Trains::DTO::Rename.new(:age, :alive_since),
Trains::DTO::Rename.new(:whatup, :name)
],
removed_columns: %i[title]
)
}
)
Expand Down
17 changes: 16 additions & 1 deletion spec/lib/trains/visitor/model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,29 @@
it 'generates migrations for association method calls' do
model = <<~RUBY
class AccountPin < ApplicationRecord
has_and_belongs_to_many :accounts
self.ignored_columns = [:foo, bar, :baz, 'what']
end
RUBY

parser = described_class.new
model_ast =
RuboCop::AST::ProcessedSource.new(model, RUBY_VERSION.to_f)
model_ast.ast.each_node { |node| parser.process(node) }

expect(parser.result).to eq(
[
Trains::DTO::Migration.new(
table_name: 'AccountPin',
modifier: :ignore_column,
fields: [
Trains::DTO::Field.new(:foo, nil),
Trains::DTO::Field.new(:baz, nil),
Trains::DTO::Field.new(:what, nil)
],
version: nil
)
]
)
end
end
end

0 comments on commit b6d44ab

Please sign in to comment.