Class: BulletTrain::SuperScaffolding::Scaffolders::CrudScaffolder

Inherits:
BulletTrain::SuperScaffolding::Scaffolder show all
Defined in:
lib/bullet_train/super_scaffolding/scaffolders/crud_scaffolder.rb

Instance Attribute Summary

Attributes inherited from BulletTrain::SuperScaffolding::Scaffolder

#argv

Instance Method Summary collapse

Methods inherited from BulletTrain::SuperScaffolding::Scaffolder

#initialize

Constructor Details

This class inherits a constructor from BulletTrain::SuperScaffolding::Scaffolder

Instance Method Details

#runObject



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
# File 'lib/bullet_train/super_scaffolding/scaffolders/crud_scaffolder.rb', line 5

def run
  unless argv.count >= 3
    puts ""
    puts "🚅  usage: bin/super-scaffold crud <Model> <ParentModel[s]> <attribute:type> <attribute:type> ..."
    puts ""
    puts "E.g. a Team has many Sites with some attributes:"
    puts "  bin/super-scaffold crud Site Team name:text_field url:text_area"
    puts ""
    puts "E.g. a Section belongs to a Page, which belongs to a Site, which belongs to a Team:"
    puts "  bin/super-scaffold crud Section Page,Site,Team title:text_field body:text_area"
    puts ""
    puts "E.g. an Image belongs to either a Page or a Site:"
    puts "  Doable! See https://bit.ly/2NvO8El for a step by step guide."
    puts ""
    puts "E.g. Pages belong to a Site and are sortable via drag-and-drop:"
    puts "  bin/super-scaffold crud Page Site,Team name:text_field path:text_area --sortable"
    puts ""
    puts "🏆 Protip: Commit your other changes before running Super Scaffolding so it's easy to undo if you (or we) make any mistakes."
    puts "If you do that, you can reset to your last commit state by using `git checkout .` and `git clean -d -f` ."
    puts ""
    puts "Give it a shot! Let us know if you have any trouble with it! ✌️"
    puts ""
    exit
  end

  child = argv[0]
  parents = argv[1] ? argv[1].split(",") : []

  # Raise an error if the developer skipped adding the parent and went straight to the attributes.
  if FIELD_PARTIALS.keys.map(&:to_s).include?(parents.first.split(":").last)
    puts "It looks like you forgot to add the model's parent to your scaffolding command.".red
    puts "Add the parent name after the model and try again.".red
    exit
  end

  parents = parents.map(&:classify).uniq
  parent = parents.first
  child_parts = child.split("::")
  parent_parts = parent.split("::")

  # Pop off however many spaces match.
  child_parts_dup = child_parts.dup
  parent_parts_dup = parent_parts.dup
  parent_without_namespace = nil
  child_parts_dup.each.with_index do |child_part, idx|
    if child_part == parent_parts_dup[idx]
      child_parts.shift
      parent_parts.shift
    else
      parent_without_namespace = parent_parts.join("::")
      break
    end
  end

  # get all the attributes.
  attributes = argv[2..]

  check_required_options_for_attributes("crud", attributes, child, parent)

  # `tr` here compensates for namespaced models (i.e. - `Projects::Deliverable` to `projects/deliverable`).
  parent_reference = parent_without_namespace.tableize.singularize.tr("/", "_")
  tableized_child = child.tableize.tr("/", "_")

  # Pull the parent foreign key from the `create_table` call
  # if a migration with `add_reference` hasn't been created.
  migration_file_name = `grep "add_reference :#{tableized_child}, :#{parent_reference}" db/migrate/*`.split(":").shift
  migration_file_name ||= `grep "create_table :#{tableized_child}" db/migrate/*`.split(":").shift
  parent_t_references = "t.references :#{parent_reference}"
  parent_add_reference = "add_reference :#{tableized_child}, :#{parent_reference}"
  parent_foreign_key = nil
  File.open(migration_file_name).readlines.each do |line|
    parent_foreign_key = line.match?(/#{parent_add_reference}|#{parent_t_references}/)
    break if parent_foreign_key
  end

  unless parent_foreign_key
    puts "#{child} does not have a foreign key referencing #{parent}".red
    puts ""
    puts "Please re-generate your model, or execute the following to add the foreign key:"
    puts "rails generate migration add_#{parent_reference}_to_#{tableized_child} #{parent_reference}:references\n"
    exit 1
  end

  unless parents.include?("Team")
    raise "Parents for #{child} should trace back to the Team model, but Team wasn't provided. Please confirm that all of the parents tracing back to the Team model are present and try again.\n" \
      "E.g.:\n" \
      "bin/super-scaffold crud Section Page,Site,Team title:text body:text\n"
  end

  transformer = Scaffolding::Transformer.new(child, parents, @options)
  transformer.scaffold_crud(attributes)

  transformer.additional_steps.each_with_index do |additional_step, index|
    color, message = additional_step
    puts ""
    puts "#{index + 1}. #{message}".send(color)
  end
  puts ""
end