How do I get bin/rails app:template LOCATION=.. to actually work? (rails template with existing app)
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.
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.
Ah, finally found the code for the rails app:template
command: https://github.com/rails/rails/blob/9e34df00039d63b5672315419e76f06f80ef3dc4/railties/lib/rails/tasks/framework.rake
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.
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.
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.
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?