Rails and Vue Tutorial
Hello, let’s build a website using Rails and Vue.js.
Background: I started this project with the goal of building a simple site for my significant other. The request was for a tool to randomly assign students to limited numbers of computers and ipads. If we have 2 computers and 3 iPads, we want five randomly selected students to get the privilege of using them that day. The aim was to offload a process that can feel unfair to a system that would have fairness built into it. This simple goal led to a simple project for me which held a series of interesting learning opportunities that I want to share with you now.
This is best for those trying to get a basic grasp of Vue or those interested in using a JavaScript front-end framework with a Rails backend.
Disclaimer: This project and most choices made throughout are not declarations of best practices. There are many points in this project where I wound up making quick tech/tool/design choices that might not have been ultimately the best. I’ll try to note these where I can in the tutorial.
Also, this project was a free-time sort of thing, it’s been stretched out over time. There might be details I’ve forgotten or gloss over. Don’t let me get away with these, ask any questions on any points where you’re confused. I’ll clap back.
Contents:
- Getting Rails ready
- Rails and Brunch
- Writing with Vue in mind
- The dirty implementation details
- Launching to Heroku
- References and tooling sites
1. Getting Rails ready
There are some things to note at this stage that will dictate our actions. Since we’re building a Rails application with a Vue front-end, Rails will consequently be all backend. This Rails application will be very basic as it will only be JSON API endpoints for the Vue front-end to shoot at. You will see us taking default gems out and truly transforming how we interact with Rails.
Create a new rails project, I called mine techTime.
// Defaults to a SQLite database, not recommended over all.
rails new techTime -T// OR Default to a Postgres database, recommended.
rails new techTime -T -d postgresql
Next we want to prep for some RSpec testing, my preferred test tool:
rails generate:rspecNow we’re cooking.
1.1 Gemfile Configuration
View my Gemfile on GitHub.
Notable additions:
# Use postgres as the database for Active Recordgem
'pg'# Use npm as part of your Rails asset pipeline
gem 'npm-pipeline-rails'
npm-pipeline-rails requires our uglifier to be removed. This is due to a constraint in how it interprets backticks (`) in Vue components.
Notable removal:
# Use Uglifier as compressor for JavaScript assets
# gem 'uglifier', '>= 1.3.0'You may be wondering where Vue comes into play. NPM has that and others on lock, through Brunch.
Install all the gems and we can continue.
1.2 Brunch Configuration
In choosing to use the npm-pipeline-rails gem I was given several choices for build tool including Brunch, Gulp, Webpack, and others. I chose Brunch because it was the first in the list of build tools I didn’t know how to use. It turned out to be relatively simple once I started using it. Check out the Brunch docs here.
With the installation of npm-pipeline-rails, we get some automated setup commands. We want to run the following command in the terminal for setting up for Brunch:
./bin/rails generate npm_pipeline:brunchThis generates several important changes and new files:
# Add compiled Brunch files to the pipeline.
app/assets/javascripts/application.js
app/assets/stylesheets/application.css# Generate skeleton brunch-config.js file at root.
brunch-config.js# Generate skeleton package.json
package.json
These last two items are worth breaking down.
brunch-config.js: This is where you’re going to configure what Brunch does. A semi-detailed breakdown can be found in the Brunch docs here. In a nutshell this is where you’re going to tell Brunch to look for files, where to build assets to, and any other general house cleaning.
I’ve modified mine for a couple purposes. First it to explicitly order my JS files in interpretation because Brunch defaults to alphabetical and would eventually pick up something out of order. I’ll go over this again later. Second is the tool copycat-brunch, which I used for copying FontAwesome fonts to the Rails vendor folder.
package.json: For someone like myself who was new to npm, this is best described as the npm equivalent of your GemFile. All your npm-originating dependencies are here. In this case, all the front-end technologies and some instructions for Heroku, but we’ll get into that later. Read all about the package.json here.
2. Rails and Brunch
Great news, you’re working with Brunch now. Brunch will be activated automatically whenever you start your rails server but only in a limited capacity. You will want to run some build commands when working with Vue components.
brunch buildRun this anytime you make a change and make sure to kill your server to be sure you get the rebuilt files served to your application.
3. Writing with Vue in Mind
Now we can start writing up this simple application. We’re going to write a simple, yet more complex program than normal for a tutorial like this, sorry but this project was for a real person and purpose. How useful it is in real life is another story.
We’ll have several models:
- student
- group (essentially lists of Students, Assignments, and Assignment Records)
- assignment
- assignment_record
- groups_students (A join table)
Here’s the migration:
class AddEverything < ActiveRecord::Migration[5.0]
def change
create_table :students do |t|
t.string :name
t.boolean :skip
t.timestamps
end create_table :groups do |t|
t.string :name
t.timestamps
end create_table :groups_students do |t|
t.belongs_to :student, index: true
t.belongs_to :group, index: true
t.timestamps
end create_table :assignments do |t|
t.string :title
t.integer :group_id
t.timestamps null: true
end create_table :assignment_records do |t|
t.integer :group_id
t.belongs_to :student, index: true
t.belongs_to :assignment, index: true
t.timestamps
end
end
end
Let’s look at the Group model in this Vue context first since it’s very important.
3.1 Writing for the Group
Groups contain collections of Students, Assignments, and assignment records. Groups are kind of the center of the universe at the moment. Here’s what its Model file would look like:
# group.rb
class Group < ActiveRecord::Base
has_many :groups_students, class_name: GroupsStudents
has_many :students, through: :groups_students
has_many :assignments
has_many :assignment_records validates :name, presence: true
end
To be continued…