Your guide to the Rails Girls Guide!

Originally created by H Salmon to accompany the app guide.

This guide is an accompaniment to the first main numbered Rails Girls guides you will be using to build your first Rails application. Its purpose is to provide background information about the structure of a Rails application, Rails terminology and commands, so you can understand what is happening when you are implementing the code in the Rails Girls Guide. We hope that this guide will provide you with a way to retain what you learn over the course of this workshop, and to maintain your interest in Rails development. Welcome!

1. Create the application

In the build your first app guide we’ll create our first Rails app. We’ll start with these commands:

2. Create Idea scaffold

In the build your first app guide we’ll quickly make some Rails app code using scaffolding.

What is Rails scaffolding?

Every web application consists of many different concepts or resources (such as “users”, “ideas”, “posts”, “comments”, etc.). Rails scaffolding is a command (rails generate scaffold) for introducing a new resource into your application. It generates all of the code files necessary for representing and interacting with this resource.

What is a model?

In Rails, a model represents a definition of a resource in your application, and how it should interact with other parts of the application. Depending on the nature of the website, these resources could be users, posts, groups etc. When a model is generated, a corresponding database table is created. This database table contains information that represents specified attributes of the model, e.g. for a User model, there might be a ‘name’ column and an ‘email’ column, and there will be rows for each subsequent user created. In the application you are creating, these resources are ideas and the model is ‘Idea’.

rails generate scaffold idea name:string description:text

In order to create our idea model, we use the scaffold command which includes an argument with the singular version of the model name (idea), and an argument with parameters (specifications) for the model’s attributes. This means that the idea model corresponds to a table in the database with columns for the attributes specified in the command: name and description. The scaffold command also auto-generates an id attribute, referred to as the primary key, which is used to establish relationships between database tables.

The ideas table

id name description
1 “Money-spinner” “Open a moveable shop!”
2 “Champagne For Breakfast!” “We should do this every Friday!”
3 ... ...

Naming conventions

Active Record

In Rails, the default system for communicating with an application’s database is called Active Record, which provides various methods for creating, saving, and finding data. To retrieve information from the database, Active Record establishes relationships between different parts of the application using naming conventions:

Model attributes and types

As we’ve already discussed, a model can have attributes (properties) represented by columns in the corresponding database table. To be supported by the Active Record system, these attributes must conform to a list of appropriate types:

What are migrations and why do you need them?

Migrations change the state of the database. When you run the scaffold command, a migration file containing instructions for the database table relevant to your command is added to the db/migrate folder of your application. For example, when you ran the rails generate scaffold command, a migration containing instructions for our ideas table was created. There are other commands that create migrations such as the rails generate model command and the rails generate migration command.

The rails db:migrate command updates the database according to the specifications in the migration file. This command, known as “migrating up”, ensures that your idea model is added to the database. Migrations can also be undone (“migrating down”) using the command rails db:rollback.

3. Finetune the routes

In the build your first app guide replace the Rails splash page with a redirect to our ideas scaffolding.

In a functional Rails application, there is an inbuilt system in place for translating incoming requests from the browser in order to return the intended response. This system is called routing. Requests from the browser are interpreted as specific HTTP methods. HTTP (Hypertext Transfer Protocol) is the protocol that defines how information (usually webpages or webpage components composed of text with hyperlinks - ‘hypertext’), is formatted and transmitted across the internet. There are four primary HTTP methods, each of which is a request to perform an operation on a specific resource (e.g. users, posts); GET, POST, PUT and DELETE. Rails’ inbuilt routing system automatically generates routes for each resource that map to specific actions (index, show, new, edit, create, update, delete) defined in the controller. So, for each of our models, there are seven related actions defined in the associated controller, ideas_controller.rb. These actions specify the appropriate response (a ‘method’) which is most likely to render the corresponding view, e.g. ideas/index.html.erb.

HTTP Method Path Action used for
GET /ideas index displaying a list of all ideas
GET /ideas/new new returning an HTML form for creating a new idea
POST /ideas create creating a new idea
GET /photos/:id show displaying a specific photo
GET /photos/:id/edit edit returning an HTML form for editing a specific photo
PUT /photos/:id update updating a specific photo
DELETE /photos/:id destroy deleting a specific photo

If you look in your ideas_controller.rb you can see these actions and the associated behaviour, and the HTTP method that corresponds with each action:

# GET /ideas/1 or /ideas/1.json
def show
end

show - the controller action

# GET /ideas/1 or /ideas/1.json - this is a comment to let us know which HTTP method and paths this action responds to.

The show action looks empty, but two things happen behind the scenes. First, the line before_action :set_idea, only: %i[ show edit update destroy ] at the top of the controller tells Rails to run the set_idea method before these actions. This method loads the requested idea from the database and makes it available as @idea. Then Rails renders the view that matches the requested format: if the browser requests HTML, the view show.html.erb is rendered. If JSON is requested (the /ideas/1.json path), the view show.json.jbuilder is rendered instead, which returns the idea’s data in JSON format so other programs can read it.

Actions that change data (create, update and destroy) look more complex. They use a respond_to helper method, which tells Rails to execute the subsequent block of code (the code enclosed by the do...end syntax) and pick the HTML or JSON response depending on the nature of the request:

# POST /ideas or /ideas.json
def create
  @idea = Idea.new(idea_params)

  respond_to do |format|
    if @idea.save
      format.html { redirect_to @idea, notice: "Idea was successfully created." }
      format.json { render :show, status: :created, location: @idea }
    else
      format.html { render :new, status: :unprocessable_content }
      format.json { render json: @idea.errors, status: :unprocessable_content }
    end
  end
end

(This code is difficult to dissect with much clarity at this stage but if you persist with Rails you will get a better understanding as time progresses.)

So, URL requests, translated into HTTP methods, are mapped to controller actions which tell Rails to return a view.

When we insert the code root to: redirect("/ideas") into our config/routes.rb, it tells Rails to make the default root of our application http://localhost:3000/ideas (note Localhost is being used as the domain because our application is still in development, when you launch your application this domain will be different). This URL contains a path (/ideas) which, by default, maps the URL to the ‘index’ action of our ideas controller and renders the associated view; index.html.erb.

4. Design

In the Style your app using HTML and CSS guide we’ll add HTML and CSS to the app to customize it.

In a Ruby on Rails application, the user interface (what someone visiting the website will see), is often written in HTML with Embedded Ruby (ERB) code. This code is contained in a specific directory called ‘views’, located in the app folder of your Rails application directory.

HTML

HTML, which stands for HyperText Markup Language, is the primary language for creating web pages and other information that can be displayed in a web browser. HTML is written using tags, angle brackets which tend to come in pairs (a “start tag” and an “end tag”), enclosing text-based content. In paired tags, the end tag also has a slash after the opening angle bracket, to distinguish it from the start tag. A paragraph (represented in HTML by the letter ‘p’) would use a start tag like this: <p> and an end tag like this: </p>, to enclose the text intended for display. Unpaired tags that are opened but don’t need to be closed (e.g. <br>, which defines a single line break) are known as “empty elements”. The web browser uses HTML tags to interpret how the contents will be displayed.

ERB: Embedded Ruby

ERB is a system supplied by Ruby that allows you to insert pure Ruby code into files written in other languages, such as Javascript or HTML. The Ruby code is contained within specific angle brackets (<% and %>) which instruct the system to execute the contents. If an = sign accompanies the angle brackets, (<%= and %>) then the contents are executed and rendered on the page.

For example, if you had 25 active ideas in your application, the code: There are currently <%= Idea.count %> active ideas would render as:

There are currently 25 active ideas

MVC Architecture

In a standard Rails application (like you one you have generated), the app/ folder of your application starts out with three folders (or directories): ‘models’ (which we have already discussed), ‘controllers’ and ‘views’. The relationship between these directories is the foundation (known as MVC Architecture) of the application, and of Rails development.

When you ran the rails generate scaffold command, in addition to creating the idea model, you also created an accompanying ideas controller (ideas_controller.rb), located in the controllers folder, and an ideas views folder containing several files that you will use to create a dynamic application.

When attempting to display a Rails website, a web browser sends a request via the server which eventually hits the Rails controller. Controllers act as mediators between the views and the models. When the controller receives the information, it communicates with a model representing a resource of the application (in our case, an “idea”) which in turn communicates with the database. Upon retrieving the required information from the model, the controller renders the view which returns the complete web page to the browser as HTML.

CSS and layouts

CSS (Cascading Style Sheets) is a language used to describe the formatting of pages written in a ‘markup language’, i.e. a language for processing, defining and presenting text with a prescribed formatting code e.g. tags, that distinguish it from plain text. The most common application of CSS is in conjunction with HTML.

For each Rails application there is a default layout file called application.html.erb, located in the layouts folder of your views directory. With this file you can create a default format for all of the pages in your application.

<link rel="stylesheet" href="https://railsgirls.com/assets/bootstrap.css">

In the above code, the link rel (link relation) is defining the nature of the URL that the href (hypertext reference) attribute is requesting content from. This argument indicates that the external source requested is a stylesheet and the web browser will need to fetch this file to render the page properly.

<%= stylesheet_link_tag "application" %>

This code returns a stylesheet link tag for the source, in this case “application”, i.e. application.css. This means that the styling you implemented in application.css will be applied to the various pages of your application.

<div class="container">
  <%= yield %>
</div>

In this code:

5. Add picture uploads

In the Add picture uploads we’ll add a way to uploads pictures to ideas.

Active Storage

Rails comes with a built-in feature for file uploads called Active Storage. It stores the uploaded files and uses two extra database tables to link the files to records, like the ideas in your application. This is why we run the rails active_storage:install and rails db:migrate commands before using it. The has_one_attached :picture line in the Idea model tells Rails that every idea can have one attached file, named picture.

Libraries

Many programming languages, including Ruby, use a wide range of libraries. In Ruby’s case, most of these libraries are released in the form of self-contained packages called gems, which contain all the information required to install and implement them. These gems are contained in your application’s Gemfile and if you look in this file you’ll notice that when you created your first Rails application it came with several gems that ensure your application functions correctly.

Gems help simplify and prevent repetition in a developer’s code, in keeping with the DRY (Don’t Repeat Yourself) principle of software development. Gems may solve specific problems, add specific functionality, or address specific requirements, meaning that should another developer encounter a similar scenario, instead of writing new code, they can install a gem containing pre-written code. For example, “image_processing”, the gem you add in the Create picture thumbnails guide, is designed to make it easy to resize images in your application.

“Bundler” is the software Ruby uses to track and manage gems. The bundle install command runs Bundler and installs the gems specified in your Gemfile. You’ll notice the code source "https://rubygems.org" at the top of your Gemfile. Whenever you add a gem to your gemfile and run the bundle install command, this code tells your application to fetch the gem from https://rubygems.org. “RubyGems” is a Ruby-specific packaging system, the purpose of which is to simplify the creation, sharing and installation of gems.

Open-source software

Both the Rails framework and the Ruby language are examples of open-source software. Open-source software is released under a licence which ensures universal access; anyone has the right to change, study and distribute the software. Making the source code accessible enables the establishment of a diverse, reflexive, collaborative and consequently ever-evolving interactive community of programmers who all benefit from each others’ developments.

More HTML

The file app/views/ideas/_form.html.erb contains HTML code that determines the look and feel of the form used for editing and creating ideas (the edit.html.erb and new.html.erb views). A partial is a snippet of HTML and Ruby code that can be reused in multiple locations. The form for editing existing ideas and the form for creating new ideas will look pretty much the same, so it makes sense to have one form for both files to use. If you look in these files you’ll notice that they have a customised heading (e.g. <h1>Editing idea</h1>) and then they simply say <%= render "form" %> which tells Rails to render the partial _form.html.erb.

If you take a look in the _form.html.erb file, you will see the code form_for in the first line of code. This is a block used to create an HTML form. Using this block, we can access methods to put different input fields in the form.

The code we are implementing, <%= form.file_field :picture %>, tells Rails to create a file input on the form and attach the submitted file to the ‘picture’ attachment of an ‘idea’. We use file_field instead of text_field because file_field makes it easier for the user to select the image they wish to upload.

In the code <%= @idea.picture %>, @idea is known as an instance variable. Instance variables are prefixed with an @ symbol and are defined in the controller action that corresponds with the view in which they are referenced. For the purposes of the code we are implementing, @idea is defined in the ‘show’ action of the Ideas controller, with the code @idea = Idea.find(params[:id]). This makes it available for us to use in the view show.html.erb. It could be defined differently in different controller actions (e.g. index or new). The code @idea = Idea.find(params[:id]) uses the Rails find method to retrieve specific ideas from the database.

The code that follows the @idea variable (.picture) tells Rails to access the ‘picture’ attachment of our resource (idea). In the code <%= image_tag(@idea.picture...) we are using the Ruby image_tag helper which translates to an HTML <img> tag (used to define images in HTML). Given the picture attachment, the image_tag helper creates a path to the image associated with a particular idea.

You will notice that within this block of code you are implementing we are also able to set a default width for each image (width: 600). The final part of the code, if @idea.picture.attached?, tells Rails to check whether a picture is attached to the idea before rendering the image tag.


Want to learn more? View more guides!