Skip to main content
37 Rails Concepts:

Rails Application Templates

Episode 235 · March 21, 2018

Learn how to build Rails app templates to save time building new applications and check out Jumpstart, the template used to build new Rails apps for GoRails episodes


Transcripts

What's up guys? This episode we're diving into rails application templates, now this has been a requested topic a lot, because I've been making these episodes and I start off a lot of these episodes with an application that's already kind of pre configured, and it has bootstrap and font awesome and devise and a few other things already set up so that we can focus that video on the feature we're talking about, so this episode I'm going to walk you through how I set up those applications and give you that template so that you can set up your applications using this as well. What I'm using is a rails application template, and this is basically just ruby scripts that you pass in when you create a new rails app, and after it's done creating the new rails app, it runs the code in your script to add things to the gem file, to configure files, to modify files that, to add routes or environment configurations, all kinds of different things, and that will go and preconfigure your rails app so when you're done, you have an app that's already good to go with several things already configured and you can save yourself a lot of time.

This stuff is all built of something called "Thor", and so if you want to do some more advanced things, like copying files and things like that, thor has actually got a lot of documentation that you want to check out, as well, because th rails application template guide, is really just rails specific kind of stuff for the most part, it shows you how to add gems, add routes, create scaffolds or generate models, that type of thing, and all of that is great and all but it's a lot of stuff that you wouldn't necessarily have to do if you're building something outside of rails. Thor is something you want to check out as well, and jumpstart is my template that I've created for the Gorails screencast.

The way that this works and how to use the template is first you're going to want to create a new application. This does not apply to existing applications unfortunately, but it would be too complicated if it had to, so we only can use this on new rails apps, and what you can do is add two options. You can either clone the repository and then reference the template file, which is the second example, or if the templates have been configured properly, you can actually use it through the url. I need to make a change to this because I'm using the copy file function, and with the URL function it actually can´t find all the files, and then that version will fail currently, but we're going to make a fix to that so that it will work after this episode. Let's take a look at what it looks like when you create a new app from scratch on the command line, after you've done a git clone of jumpstart. Here I've got a clone of jumpstart, we can print that out, and I've already got an application called myapp in here that I've created with it. When you want to create a new application, you'll call it whatever you want, and then you'll specify that template.rb, and optionally, you can say, I want to use PostgreSQL, MySQL, whatever it is, I would recommend Postgres. In this example I'm just going to use SQL lite to keep it easy, and I'm going to create a new application called whatever. You'll see here that it creates a new app like normal, except it's going to take a lot longer, and the reason for that is it's applying this template, and so here you can see it reference the template, it's adding to the gemfile administrate, devise, bootstrap, all these other gems that I've specified in my template, and it's going to go through and install all that, do everything that I've configured it to do. Once this is done we'll have a brand new rails application with all that stuff preconfigured for us, and we can just dive into using it. The way that these templates work, is you write a big old ruby script, and of course you can split this out into other files if you wanted, but for the most part it's pretty straightforward. I created and organized functions to do different things like add gems, add the user model and some other configuration or related to users. Got adding bootstrap, copying the templates, add webpack, add Sidekiq and so on, you can see all these methods, describe what they do and we can organize them however we like, and then here at the bottom, when this script gets run, it will run each of these methods in order, so first we're going to add the gems, then after it has run bundle install, then we're going to add the users, bootstrap, Sidekiq, foreman, webpack and all of those gems are already installed, but the configurations are not, so we're doing it after the gems there, so we can set up the configuration correctly. Then, it goes through all these commands, and we then copy some templates and run rails db:create, rails db:migrate and we run administrate and commit all of that to your git repo, so it's pretty cool what it does and all of these things are broken down into those commands that are listed on the template API for rails application templates. They are gem, to add a gem to your gemfile, you can run a generate command, so if you've got the devise gem installed, you can run rails generate devise:install That works just like you would expect it. The environment option is really cool, you can specify your development environment, should have this config ActionMailer default url options pointing to localhost:3000. Devise views bootstraps can be run, we can add routes to our routes file, and then you can use some gsubs and thing like the underlying Thor functionality will give you such as with this migration, we actually want to set the admin flag is false by default and so we can go and use gsub file in order to modify that file, we get the file name, what we're looking for and the replacement text and that will do the update of the file for us. Now that our application is properly generated, let's go into it and run mvim . so we can take a look at what we've got.

Now, one of the first files that you'll notice is the most configured is actually your routes file, and that file actually has a section up here for administrate, it's got a couple routes that I've added for privacy policy and terms of use, because pretty much every application needs that, we've got notifications and announcements, we've got a section for Sidekiq which is authenticated using devise, and we've got our device line here already configured to use our Omniauth callbacks and our homepage is set to home#index. All of that is done automatically with that script which is really really handy. So, let's take a look at how this application works. The way that we need to run this now is using our Procfile. So the Procfile sets up a rails server, sidekiq and our webpack dev server and we're going to need to use Foreman start instead of rails s in this case because we want to make sure that all three of those are running and that will get us up to speed the fastest. With that said, this is going to run on localhost:5000 now because we're using the Foreman port, you can actually specify the port inside the Procfile to be localhost:3000 if you want, but once that's booted up you're going to get a new application like so that's already got your navbar and your sticky footer, so this footer will always be at the bottom of the page, that is already set up using bootstrap, and all of our device views have what we have here which is the devise bootstrapped gem that a fellow community member Andrew Fomera built, and so that gem is going to configure our devise views to use bootstrap we don't have to do any of that work ourselves unless we want to tweak it. So right now we have an application that doesn't really do too much just yet, but let's add let's say a Post model so we have something to interact with, so I'm going to add a scaffold for Post, and I have user references and have a title and a body, and we're going to add this to our application, so you can see just how quickly we can get up to speed with something like this, so we'll run rails db:migrate, we'll go to our routes file, we're going to take this resources post and we're just going to move this down here to the bottom, and then we'll change that to posts index as the root route and that way we'll see posts automatically on the home page. Then we can go to our posts controller that we just generated and we'll set it up so that when we create a post @post.user = current_user, and we'll say before_action :authenticate_user, except: [:index, :show]. Index and show will be available to any logged out users, but if they want to create, edit, or destroy a post they will have to log in. That will be just a really simple example of how to do that, then we can go to our application, and we'll see that we now have post here, I will not fill out the user there, so let's go to the post form. Now, let's get rid of that user section, then we can go replace these with form group, form group and form group, add class of btn btn-primary to our button, and class of form control to our fields, and that's going to make it styled with bootstrap, a little nicer, and then we'll have test posts and some content for the body and we can create our post and that will be there on the home page, so all of those work, and one cool thing is that we have an admin area from administrate, but we can't access it right now, and we can't go to /admin because we're not authorized, so it's automatically configured to authorize that only for admin users, and the way to set up an admin user is to run rails console, User.last.update(admin: true), so we'll set that user to be an admin, if we refresh our page, the admin area now shows up in the nav bar and if we click that, we get taken to administrate.

One thing we don't ahve is this was already generated before we added the posts, so we need to create the dashboard for posts, so we can do that by running rails g administrate:dashboard Post. Now we'll create the Post dashboard and Post controller for administrate, that will show up here but only after we create the routes for it. So it doesn't actually generate the routes, which feels kind of weird, maybe that will be a feature that they add in the future for administrate, but in your namespace admin you need to set resources post in there as well in order to get it to show up. Now we have posts, and we can see our user one, and even if you click on user one it will go to the correct user which is nice, administrate works really well for this, and gives quite a good little application that we can start with that is a foundation for all of the gorails episodes that I've been doing for the last, you know, year or something when I've been using this template, so it's been really nice to have this because it gets us up and running a lot faster.

Probably my favorite thing about these templates is just how much you can imagine adding to these to make your life easier, for example, it would be really nice if it added payments, and email receipts and all kinds of other things like Stripe and Braintree support, you can just imagine a lot of other things being built into this and having that automatically ready to go as soon as you create your new application, maybe even including something like ahoy or Segment IO so that you can add analytics to your application, that would be incredibly cool, but even if it was as simple as adding overrides to your templates for scaffolds, where they would automatically come out with bootstrap designs like the form here, or it redesigned the index page so it used nicer bootstrap layouts or UI, that even would be a huge improvement that could save a lot of time on building new applications. With these templates you can go as far as you want or even minimal and you will still save a lot of time.

That is it for this episode, I'll include a link to jumpstart in the notes below, so if you want to add this to your rails apps or you want to contribute to it or just check out how it works, it will be listed on the links below as well as links to the rails guides and thor's documentation so you can take a look at how to build your own from scratch. Until next time, I will talk to you guys in the next episode. Peace

Transcript written by Miguel

Discussion


Fallback
Hello,

Im getting
Could not find "Procfile" in any of your source paths. Your current source paths are:
/Users/my_user/Documents/dev/my_app/https:/raw.githubusercontent.com/excid3/jumpstart/master
Using this command:

rails new myapp -d postgresql -m https://raw.githubusercontent.com/excid3/jumpstart/master/template.rb
Also tried this one (downloading the repo):
rails new myapp -d postgresql -m template.rb

The installation hung up, and when I interrupted it and tried to do "foreman start", got:
+ERROR: Procfile does not exist

Any help making the template work ?

Best regards,
Leonardo
Fallback
Hey Leonardo,

If the Procfile didn't exist, I would imagine that the full template didn't run successfully. I've made a handful of extra changes since the episode so you might want to try it again. I still haven't fixed the HTTP version of it so you'll need to use the downloaded repo still.
Fallback
Hello Chris,

Thanks for you reply, I updated my local jumpstart repository and got another error:
Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)
But it was because I didnt have Redis server installed, after I installed it, everything worked ok.

Thanks for your help,
Leonardo

Fallback
Had the same issue with Redis not installed but also needed to install foreman before everything worked like a charm! Thanks Chris!
~Uzi

Fallback
Hi!

I came across an error when I was trying to generate a scaffold:
(erb):1:in `template': undefined local variable or method `model_resource_name' for #<Erb::Generators::ScaffoldGenerator:0x00007fd4e005ccf8> (NameError)

I had to replace every occurrence of model_resource_name with singular_name in the file lib/templates/erb/scaffold/_form.html.erb in the newly created app folder. 
Example:
<%%= form_with(model: <%= model_resource_name %>, local: true) do |form| %>
becomes
<%%= form_with(model: <%= singular_name %>, local: true) do |form| %>

Best regards,
Mark
Fallback
Thanks for the heads up! I was working on overriding the scaffolds like I mentioned in the video and this was one of the errors I ran into. I think I already fixed it but forgot to push it up.
Fallback
Actually, I bet it's just that you're not using the latest version of Rails 5.2 (rc1 and rc2 are what I'm using). I don't think the beta will work because it looks to have changed in this commit: https://github.com/rails/rails/commit/cf56397ccd10174d94f60331e4a55ff765b3485b

"gem install rails --pre" should fix your problem or just update it in your Gemfile to rc2.

Fallback
Awesome video, thanks for sharing!

Fallback
Hello. I'm trying to publish only the basic template in Heroku, but getting error: 

Redis::CommandError: ERR max number of clients reached
https://dashboard.heroku.com/apps/parolin-celula/logs

It's working well in my localhost. 

Fallback
Hey Gustavo,

Sounds like your Redis instance on Heroku has a maximum number of connections. You might need to reduce the concurrency on Sidekiq or something to create less Redis connections (or increase your Redis node).

Fallback
Hello Chris,

      While scaffolding I am getting undefined method `model_resource_name' .  Did I miss anything?

template': undefined local variable or method `model_resource_name' for #<Erb::Generators::ScaffoldGenerator

Fallback
Make sure you're using Rails 5.2 when you use the template. We're only going to support that version since it's almost released and we can take advantage of things like ActiveStorage.

Fallback
Hey @chris, I have a brand new Ubuntu OS install and have installed refresh Ruby 2.5 and Rails 5.2 running 
the new app command as you mention I am getting the following errors. Any idea why this might be? It builds app but seems to fail everything else after...

Sorry... Link here.
https://drive.google.com/file/d/178Krtd3HP499LRzDacuxKKula-P4ea3s/view?usp=sharing

Fallback
Hey Josh,

Administrate gem just needed updating. Should be fixed now!
Fallback
That did the job. :) Legend. Thank you.

Fallback
Hi Chris 
Thanks for your work on this. For someone with low experience, this is massively helpful! 
That said I'm still battling to get it running.
 My local environment is Os X 10.13.6. I have new installs of Rub 2.5 and Rails 5.2.
I've installed yarn, redis, foreman;
but still seem to be having issues with getting Jumpstart to work.

It seems to be something about:
You need to allow webpack-dev-server host as allowed origin for connect-src. 
This can be done in Rails 5.2+ for development environment in the CSP initializer 
config/initializers/content_security_policy.rb with a snippet like this: 
policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?

Here are the errors:
https://www.dropbox.com/sh/w05wxfunrj71rwp/AAAF-7nlhaIw5XBapoiqnNura?dl=0

Any help you could lend would be greatly appreciated so I can get onto doing your other Series.


Grant

Fallback
Update: ok it appears to have been an issue with Redis not initiating properly. I reinstalled at it's resolved the issue. 

Fallback
Thanks for awesome video!
I want to try and follow this tutorial but i have an err when i make a new app.
------------------------------------------------------------

generate  devise:views:bootstrapped 
=> err : Traceback (most recent call last):

-----------------------------------------------------------
i have an traceback err and i have no idea why this is happen?
someone please help me. 
( any hint is okay )


Fallback
Hey Lee,

You need to include the other lines as well after the error because that's what we use to debug what went wrong. Without it, we can't tell what happened.
Fallback
Hi Chris

i tried to find out what's the problem,
and i made a code size much smaller to find out the problem.

i just make a code size to a basic size,
and this basic template also didn't work properly,

problem is occurred when start generate something.
i captured the code and terminal lines,

 code & errs :  https://imgur.com/a/no9qOav

( this kind of similar err is occurred when running "jump start :  template.rb" )


Fallback

Hi Chris, great video and I would love to use this template.

I've been stuck with this issue for ages, please help! 

When I run foreman start ...

|     + 11 hidden modules
07:55:40 webpack.1 | webpack: Compiled successfully.
07:55:48 web.1 | => Booting Puma
07:55:48 web.1 | => Rails 5.2.0 application starting in development
07:55:48 web.1 | => Run rails server -h for more startup options
07:55:57 sidekiq.1 | 2018-06-30T06:55:57.652Z 30469 TID-ov3hhgys5 INFO: Running in ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
07:55:57 sidekiq.1 | 2018-06-30T06:55:57.652Z 30469 TID-ov3hhgys5 INFO: See LICENSE and the LGPL-3.0 for licensing details.
07:55:57 sidekiq.1 | 2018-06-30T06:55:57.652Z 30469 TID-ov3hhgys5 INFO: Upgrade to Sidekiq Pro for more features and support: http://sidekiq.org
07:55:57 sidekiq.1 | 2018-06-30T06:55:57.652Z 30469 TID-ov3hhgys5 INFO: Booting Sidekiq 5.1.3 with redis options {:id=>"Sidekiq-server-PID-30469", :url=>nil}
07:55:57 sidekiq.1 | Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:344:in rescue in establish_connection'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:328:in
establish_connection'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:99:in block in connect'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:291:in
with_reconnect'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:98:in connect'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:363:in
ensure_connected'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:219:in block in process'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:304:in
logging'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:218:in process'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:118:in
call'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis.rb:274:in block in info'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis.rb:45:in
block in synchronize'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in mon_synchronize'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis.rb:45:in
synchronize'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/redis-4.0.1/lib/redis.rb:273:in info'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq.rb:113:in
block in redis_info'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq.rb:95:in block in redis'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:65:in
block (2 levels) in with'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:64:in handle_interrupt'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:64:in
block in with'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:61:in handle_interrupt'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:61:in
with'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq.rb:92:in redis'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq.rb:106:in
redis_info'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sidekiq-5.1.3/lib/sidekiq/cli.rb:80:in run'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sidekiq-5.1.3/bin/sidekiq:12:in
<top (required)>'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/bin/sidekiq:23:in load'
07:55:57 sidekiq.1 | /Users/jamesweetland/.rbenv/versions/2.5.1/bin/sidekiq:23:in
<main>'
07:55:58 sidekiq.1 | exited with code 1
07:55:58 system | sending SIGTERM to all processes
07:55:58 web.1 | Exiting
07:55:58 webpack.1 | exited with code 0
07:55:58 web.1 | terminated by SIGTERM
Fallback
Like the error mentions:
07:55:57 sidekiq.1 | Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)

Make sure you have Redis installed and running. Anytime you have a connection refused for any service like Postgres, MySQL, Redis, etc, it means it's not running. 

Fallback
haha so obvious! my bad thanks Chris!
Fallback
You're all good, easy to overlook those things sometimes! :D

Fallback

Jumpstart Giving me This error
gsub app/dashboards/announcement_dashboard.rb
/Users/noman/.rvm/gems/ruby-2.4.1/gems/thor-0.20.0/lib/thor/actions/file_manipulation.rb:263:in `binread': No such file or directory @ rb_sysopen - /Users/noman/Projects/UOB/uob/uob/app/dashboards/announcement_dashboard.rb (Errno::ENOENT)

Fallback

Hmmm, it sounds like Administrate didn't generate a dashboard file for the Announcement model. That's weird.


Login or create an account to join the conversation.