Class: BulletTrain::SuperScaffolding::Scaffolders::JoinModelScaffolder
- Inherits:
-
BulletTrain::SuperScaffolding::Scaffolder
- Object
- BulletTrain::SuperScaffolding::Scaffolder
- BulletTrain::SuperScaffolding::Scaffolders::JoinModelScaffolder
- Defined in:
- lib/bullet_train/super_scaffolding/scaffolders/join_model_scaffolder.rb
Instance Attribute Summary
Attributes inherited from BulletTrain::SuperScaffolding::Scaffolder
Instance Method Summary collapse
Methods inherited from BulletTrain::SuperScaffolding::Scaffolder
Constructor Details
This class inherits a constructor from BulletTrain::SuperScaffolding::Scaffolder
Instance Method Details
#run ⇒ Object
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 |
# File 'lib/bullet_train/super_scaffolding/scaffolders/join_model_scaffolder.rb', line 5 def run unless argv.count >= 3 puts "" puts "🚅 usage: bin/super-scaffold join-model <JoinModel> <left_association> <right_association>" puts "" puts "E.g. Add project-specific tags to a project:" puts "" puts " Given the following example models:".blue puts "" puts " bin/super-scaffold crud Project Team name:text_field description:trix_editor" puts "" puts " bin/super-scaffold crud Projects::Tag Team name:text_field" puts "" puts " 1️⃣ Use `join-model` scaffolding to generate the join model for use in `crud-field` scaffolding:".blue puts "" puts " bin/super-scaffold join-model Projects::AppliedTag project_id{class_name=Project} tag_id{class_name=Projects::Tag}" puts "" puts " 2️⃣ Now you can use `crud-field` scaffolding to actually add the field to the form of the parent model:".blue puts "" puts " bin/super-scaffold crud-field Project tag_ids:super_select{class_name=Projects::Tag}" puts "" puts " 👋 Heads up! There will be one follow-up step output by this command that you need to take action on." puts "" puts " 3️⃣ Now you can run your migrations.".blue exit end child = argv[0] check_class_name_for_namespace_conflict(child) primary_parent = argv[1].split("class_name=").last.split(",").first.split("}").first secondary_parent = argv[2].split("class_name=").last.split(",").first.split("}").first # There should only be two attributes. attributes = [argv[1], argv[2]] unless @options["skip-migration-generation"] = attributes.map { |attribute| attribute.gsub(/{.*}$/, "") } attributes_without_id = .map { |attribute| attribute.delete_suffix("_id") } attributes_with_references = attributes_without_id.map { |attribute| attribute + ":references" } generation_command = "bin/rails generate model #{child} #{attributes_with_references.join(" ")}" puts "Generating model with '#{generation_command}'".green `#{generation_command}` end # Pretend we're doing a `super_select` scaffolding because it will do the correct thing. attributes = attributes.map { |attribute| attribute.gsub("{", ":super_select{") } attributes = attributes.map { |attribute| attribute.gsub("}", ",required}") } transformer = Scaffolding::Transformer.new(child, [primary_parent], @options) # We need this transformer to reflect on the class names _just_ between e.g. `Project` and `Projects::Tag`, without the join model. has_many_through_transformer = Scaffolding::Transformer.new(secondary_parent, [primary_parent], @options) # We need this transformer to reflect on the association between `Projects::Tag` and `Projects::AppliedTag` backwards. inverse_transformer = Scaffolding::Transformer.new(child, [secondary_parent], @options) # We need this transformer to reflect on the class names _just_ between e.g. `Projects::Tag` and `Project`, without the join model. inverse_has_many_through_transformer = Scaffolding::Transformer.new(primary_parent, [secondary_parent], @options) # However, for the first attribute, we actually don't need the scope validator (and can't really implement it). attributes[0] = attributes[0].gsub("}", ",unscoped}") has_many_through_association = has_many_through_transformer.transform_string("completely_concrete_tangible_things") source = transformer.transform_string("absolutely_abstract_creative_concept.valid_$HAS_MANY_THROUGH_ASSOCIATION") source.gsub!("$HAS_MANY_THROUGH_ASSOCIATION", has_many_through_association) # For the second one, we don't want users to have to define the list of valid options in the join model, so we do this: attributes[1] = attributes[1].gsub("}", ",source=#{source}}") # This model hasn't been crud scaffolded, so a bunch of views are skipped here, but that's OK! # It does what we need on the files that exist. transformer.add_scaffolding_hooks_to_model transformer.suppress_could_not_find = true transformer.add_attributes_to_various_views(attributes, type: :crud_field) transformer.suppress_could_not_find = false # Add the `has_many ... through:` association in both directions. # We pass the "opposing" attribute so that both the association name and the # class name get wired up correctly in cases where they don't match. For instance # if you want an `assigned_to_membership` relationship to the `memberships` table. transformer.add_has_many_through_associations(has_many_through_transformer, attributes[1]) inverse_transformer.add_has_many_through_associations(inverse_has_many_through_transformer, attributes[0]) additional_steps = (transformer.additional_steps + has_many_through_transformer.additional_steps + inverse_transformer.additional_steps + inverse_has_many_through_transformer.additional_steps).uniq additional_steps.each_with_index do |additional_step, index| color, = additional_step puts "" puts "#{index + 1}. #{}".send(color) end puts "" end |