Ask A Question

Notifications

You’re not receiving notifications from this thread.

How do I get bin/rails app:template LOCATION=.. to actually work? (rails template with existing app)

Jeff Helman asked in Rails

I remember Chris mentioning in the "Rails Application Templates" video that he was covering only templates for new rails apps because applying templates to existing apps is "complicated." I'm beginning to really appreciate that statement.

Here's what happens when I try to apply a (stripped-down) template to an existing app:

bin/rails app:template LOCATION=mini-template.rb
     gemfile  administrate
     gemfile  turbolinks (~> 5)
     gemfile  jquery-turbolinks
     gemfile  local_time
     gemfile  https://github.com/collectiveidea/interactor-rails
     gemfile  interactor (~> 3.0)
# My "got here" comments:        
************************************
Gems from template added to Gemfile
************************************
************************************
after add_gems
************************************
# Never get to the after_bundle callback.

In other words, the gemfile updates happen as expected, but the after_bundle is never invoked.

I have searched StackOverflow and the Googleverse, but I'm finding nothing on this bin/rails app:template use case. Is its functionality an urban myth?

Thanks in advance for any advice you can provide.

Reply

A quick test applying an empty template to an existing app looks like it doesn't trigger bundle install for these. Just new apps. That may be a difference between the two that isn't documented.

The code I did find was here: https://github.com/rails/rails/blob/470e6bdac97249ca3406c635f611aa8f7df8b222/railties/lib/rails/generators/rails/app/app_generator.rb

There's a run_bundle mention in there which leads me to this:
https://github.com/rails/rails/blob/2e4c65e3afb18fc9a84d4d3ae893209efce27592/railties/lib/rails/generators/app_base.rb#L407

You can probably add run_bundle to your template to make sure it runs it. I would assume this would also trigger after_bundle code as well.

Reply
Reply

Thanks, Chris!

FYI, I added a run_bundle to my template, but the after_bundle callback was still not triggered.

As a follow-up to that, commented out the after_bundle class wrapper to just run those commands without that callback, but (predictably) that didn't work either, because those commands were trying to run before the preceding (inserted) run_bundle could complete.

Reply

OK, I walked through the framework.rake code, which (to add some color commentary to your observation above)--via

    # ...
    require "rails/generators/rails/app/app_generator"
    generator = Rails::Generators::AppGenerator.new [Rails.root], {}, { destination_root: Rails.root }
    generator.apply template, verbose: false
        # ...

led to app_generator code. In app_generator, I see a bunch of references to "template," but I am guessing the relevant code is

public_task :apply_rails_template, :run_bundle

I am too new to Ruby/Rails to be confident in my understanding of this code; my guess is that this is saying "apply the template" with the "run_bundle" option, which matches exactly with what I would hope it would want to do--yet that is exactly what is not happening.

In app_base, the only template code I could confidently understand was this:

def self.add_shared_options_for(name)
        class_option :template,    type: :string, aliases: "-m",
            desc: "Path to some #{name} template (can be a filesystem path or URL)"
# ...                                                                                   

I am pretty sure that's the syntax for invoking a template when using the rails new command with the - m option.

My rookie level of understanding is certainly not helping here, and I am really no further along toward a solution than I was at the beginning. (I have, however, learned a ton, so I'm happy about that.)

All that said, I should explain what I am trying to do with rails app:template

My Objective

My use case is very relevant to every user of a rails template like Jumpstart or its possibly-commercial successor, and the nice (commercial) one I use by @Eelcoj, a member here.

  • I want to automate the process of "retrofitting" my app to a fresh template update.

I would think that this is the primary use case of rails app:template but I am probably wrong.

  • In any case, I don't care what the solution is. I just don't want to spend hours fiddling with regenerating models, copying controllers, views, and the inevitable tweaks involved with doing all this by hand.
Reply

I don't know how you differentiate between the two, but this works for rails app:template

after_bundle do
  p "hello"
end

run_bundle
run_after_bundle_callbacks

There's probably some way to check if it's a new app and only run the last two lines if needed. Maybe by looking up the current generator name or something. I'm not sure.

Reply

And keep in mind, all this code is built on Thor. https://github.com/erikhuda/thor

Reply

Thanks Chris. This might be working, but I'm getting an error that doesn't make sense to me.

The run_bundle method executes, but it doesn't seem to actually do the bundle install. Instead, we get:
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run bundle install before trying to start your application

Here's a partial log of that run:

# .... starting from the bottom of list of Gems being added:
         gemfile  interactor (~> 3.0)
# Now my "progress debug" comments:      
************************************
Gems from template added to Gemfile
************************************
************************************
after add_gems  
************************************
    run  bundle install from "."
# FAIL ... 
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run `bundle install` before trying to start your application
************************************
Starting after_bundle method (after_bundle do ...)
************************************
   You can change application name inside: ./config/application.rb
   run  spring stop from "."
# GREAT NEWS: We're running commands, but ... 
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run `bundle install` before trying to start your application

This pattern repeats: The .. adminstrate.git is not yet checked out ... error message is thrown for most commands subsequent to the bundle install ... attempt.

From inspecting the output in my test project, it appears that the "pure" Thor commands are working, but most rails commands seem to be silently failing. This all worked:

 route  resources :user_category_budget_for_periods, only: [:index]
      remove  db/seeds.rb
      create  db/seeds.rb
      create  app/interactors
      create  app/interactors/assign_or_change_category.rb
      create  app/interactors/get_transaction_budget.rb
      create  app/interactors/update_budget_from_transaction.rb
      create  app/interactors/update_remaining_budget_in_transaction.rb

My Routes file is updated:

Rails.application.routes.draw do
  resources :user_category_budget_for_periods, only: [:index]
  resources :categories, only: [:index]
  resources :my_transactions, only: [:index]
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

and those filesystem (Thor) commands above are working, but none of the migrations are working:

generate  model MyTransaction transaction_date:datetime description user:references amount_cents:integer remaining_budget_cents:integer comment
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run `bundle install` before trying to start your application
route  resources :my_transactions, only: [:index]       # THIS WORKED!
generate  model Category name description
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run `bundle install` before trying to start your application
route  resources :categories, only: [:index]            # THIS WORKED!
generate  model UserCategoryBudgetForPeriod user:references category:references year period budgeted_amount:integer actual_amount:integer comment
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run `bundle install` before trying to start your application

... and neither did any of the other rails ... commands:

rails  db:create
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run `bundle install` before trying to start your application
    rails  db:migrate
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run `bundle install` before trying to start your application
    rails  db:seed
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run `bundle install` before trying to start your application
    generate  administrate:install
The git source https://github.com/thoughtbot/administrate.git is not yet checked out. Please run `bundle install` before trying to start your application

Last night, I did check out the Thor documentation, and I was indeed thinking about rolling something myself to work around all this.

Still ... shouldn't this work? Should I file a Rails issue?

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 81,842+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more.

    © 2024 GoRails, LLC. All rights reserved.