GOAL:

Our goal here is to build a content management system (CRUD application) using rails.

Disclaimers:

I’m using windows. If you use mac the only thing that will be different will be the terminal commands. But their substitutes are easily “google-able”. Also I personally use VS code so I’ll be writing from that perspective. Aldo there are enough steps to actually write a book. So for the sake of brevity I’ll be focusing on just the main steps.

Step 0 ) Draw out the relationships

It’s important that you draw out the relationships to truly understand what is going on. Otherwise the object relationships get really, really, really confusing and you’ll spend hours of sifting through your code trying to figure out what went wrong.

I recommend using DRAW.IO online. It’s a free tool that has a lot of cool features to help you build the perfect diagrams.

Here’s my diagram:

Step 1) Rails new application

Alright the moment we’ve been waiting for. Lets go ahead and hop into your favorite terminal.

Once we make sure we have ruby (“ruby -v”) & rails(“rails -v”) installed. And once we have decided where we want to generate this project (I recommend saving it to the desktop for easy deletion once you are done and have uploaded your code to github/ your heroku server).

Let’s go ahead and type “rails new crud_app -t”

Go grab a coffee because this could take a while.

This is going to build your application and generate all the files necessary to run your application on your local web server.

Once its done loading go ahead and hop into your favorite IDE and navigate to the file location via ide terminal (Once again I’m using VS code so I’ll be writing from that perspective.).

Now let’s make sure rails is working properly.

In the terminal run “rails s”

If it provides you a local host URL congratulations! You have your 1st rails application up and running. But for most of you that wont be the case. Most likely you (And including me on multiple occasions ) will be asked to “install yarn”

So go ahead and download yarn: https://classic.yarnpkg.com/en/docs/install/#windows-stable

Try running “rails s” again and follow the instructions rails will provide you in your terminal to help get your app running. Rails want you to be successful & it’ll provide hints to what the problem is.

And Voila! You have your 1st rails application running!

Step 2) Rails Generate Models + DB

It’s now time for us to generate our models & data base. The cool thing about rails is that it does both. WITH A SINGLE COMMAND. We’re going to generate 3 models. Post, User, & Genre. Along with whatever attributes we want our modal to have in the database.

Lets type “rails g model Genre genre_name:string” press enter

Lets type “rails g model Post user_id:integer genre_id:integer title:string description:text url:string” press enter

Lets type “rails g model User username:string password_digest:string image:string website:string location:string bio:string” press enter

What you’ll notice now is that your models are built! Don’t believe me? Look in the app/models directory. Our database is also built and ready to migrate. Take a look at the db/migrate directory.

Make sure there are no typos in your db/migrate directory for all the migrations. you ‘ll notice that all your migrations come with “.datetime ” this is a default feature provided by rails. Isn’t it cool???

Whenever your ready lets go ahead and run “rails db:migrate”

Note : We won’t be “crud-ing” for Genres so lets go ahead and hop into “db/seeds.rb” and make some seed data.

Use the following syntax “Genre.create(genre_name: ‘sad’)” and create 4–5 other genre’s

Then run “rails db:seed”

Step 3) Rails Generate Controllers + views

Just like with the models. When you generate the controllers you are able to generate the views as well. In our terminal…

Lets go ahead and type “rails g controller posts new index edit show” press enter

Lets go ahead and type “rails g controller users new edit” press enter

Note we don’t need anything for the genre controller yet. We’ll add scope methods later on.

Our views have been generated in our “/app/views” directory. And if we take a peek inside our Posts and User Controllers well see that our “routes” have been added there as well. WOW!

But we still need to hop into “config/routes.rb” to get the application working.

Step 4) Associations

Before we hop into “config/routes.rb” to get the application working. We need to set up our associations in our models. We want our associations to reflect our Entity(or Object) Relational Diagram (aka ERD). Feel free to use the syntax below. So in our case…

Genre

has_many :posts

has_many :users, through :posts

— — — — — — — — — — — — — — — — — — — — —

Post #(our join table; it joins users and genres )

belongs_to :user

belongs_to :genre

— — — — — — — — — — — — — — — — — — — — —

User

has_many :posts

has_many :genres, through :posts

These relationships are pretty much english but just in case you are still having trouble understanding.

Genre has many posts and has many users through posts

Post belongs to user and genres because its our join table

User has many posts and genres through posts

And boom we have our associations!

Step 5) Routes

Now it’s time to hop into our routes. This is where things get tricky. Initially rails will have provided some routes for you. These routes were created when we built our views. But the issue is. We want nested routes. Because 1) they are more organized & 2) they look really professional. So here’s how we’re going to do it. We’re going to put all our post routes into our user routes block. It’ll look like this

resources :users, only: [:new, :create, :edit, :update] do

resources :posts

end

resources :posts, only: [:index, :create, :update]

Lets go head and delete all our post routes and our user routes and replace them with the code above.

Note: When you use “resources” you call on all the routes that have been built for the controller.

Note: When you use “resources” with an “only” you call on all the routes that have been built for the controller that are within the “only” parentheses.

Step 6) CRUD

We’re using crud in 2 different places in the Post and User objects. So let’s start with the Post, get that working then let’s hop into the User.

Lets go ahead and set up our forms in the post views route.

In “app/views/posts/new.html.erb”

&

In “app/views/posts/edit.html.erb”

<%= form_for(@post) do |f| %>

<%= f.label :url %><br>

<%= f.text_field :url %><br>

<%= f.label :title %><br>

<%= f.text_field :title %><br>

<%= f.label :description %><br>

<%= f.text_field :description %><br><br>

<%= f.label :genre %><br>

<%= f.collection_select :genre_id, Genre.all, :id, :genre_name %><br><br>

<%= f.submit “Submit” %>

<% end %>

For now we are going to put the same code in 2 different views but we will refractor(clean up) towards the end of the project.

Posts

Index:

def index

get_all_posts

end

Create:

def new

@post = Post.new

end

def create

@post = Post.new(post_params)

@post.user_id = session[:user_id]

if @post.save

redirect_to posts_path

else

render :new

end

End

Once a form is submitted it’ll be processed through the create action and redirected to the index page.

Read:

def show

render :layout => ‘logged_in_show’

end

We are also able to look at each post individually.

Update:

def edit

if !check_users_post?

redirect_to posts_path

end

end

def update

if @post.update(post_params)

redirect_to posts_path

else

render :edit

end

end

We can update our post through this action and upon a successful update we are redirected towards the index page.

Delete

def destroy

if check_users_post?

@post.destroy

redirect_to posts_path

end

end

We can delete a post here.

Users

Create:

def new

@user = User.new

render :layout => ‘signup_login’

end

def create

@user = User.new(user_params)

no_image_user

if @user.save

session[:user_id] = @user.id

redirect_to login_path

else

render :new, :layout => ‘signup_login’

end

end

Once a form is submitted it’ll be processed through the create action and redirected to the login page. But this time it will create a User.

Update:

def edit

current_user

render :layout => ‘logged_in’

end

def update

current_user

if @user.update(user_params)

redirect_to posts_path

else

render :edit, :layout => ‘logged_in’

end

end

You can Edit and Update a user profile.

Notice how we intentionally left out the other controller actions.

Step 7) helpers

We need to build out helpers to clean up our code. In the code you see above the helpers are pre- built for us at this point we just need to define them. In a normal work flow. I’d probably build the helpers as I go.

Let’s hop into the application_controller.rb and set our helpers there so that they’ll be available in all the other controllers.

def current_user

@user = User.find_by(id: session[:user_id])

end

def current_post

@post = Post.find(params[:id])

end

def get_all_posts

@posts = Post.all

end

def logged_in?

!current_user.nil?

end

def authorized

redirect_to ‘/login’ unless logged_in?

end

def check_users_post?

current_post.user_id == current_user.id

end

def no_image_user

if @user.image == nil

@user.image = “https://ombud.alaska.gov/wp-content/uploads/2018/01/no-user.jpg"

end

end

Step 8) views

Now lets go ahead and set up our views. Everyone’s views are going to differ and since this is not a html/css tutorial im going to keep this part short. Just have fun with the view’s. Really make the project your own.

Couple of things to remember.

  1. Your html files are technically erb files. So you can actually use ruby code within them.
  2. Don’t forget the difference between “<%%>” & “<%=%>”
  3. The <%%> only allows you to process ruby code.
  4. The <%=%> only allows you to display the output of ruby code

Step 9) partials

Now that our views are built let’s go ahead and clean up the repetitive code that we mentioned earlier. We’re going to clean up our code using partials. Partials are partial layouts and they really come in handy for keeping your code clean and not error prone. So a good place to start would be the create and edit forms in the post’s view.

Right now they look like this:

<%= form_for(@post) do |f| %>

<%= f.label :url %><br>

<%= f.text_field :url %><br>

<%= f.label :title %><br>

<%= f.text_field :title %><br>

<%= f.label :description %><br>

<%= f.text_field :description %><br><br>

<%= f.label :genre %><br>

<%= f.collection_select :genre_id, Genre.all, :id, :genre_name %><br><br>

<%= f.submit “Submit” %>

And we can actually clean up the code into this:

<%= render ‘form’ %>

The first thing that we have to do is to create a file called “_form.html.erb”. Rails knows this is a partial because of the underscore “_” in front of the title.

Next well “cut” (ctrl + x) our code out of the “new.html.erb” view and put it into the “_form.html.erb”

Once completed. Lets go ahead and paste “<%= render ‘form’%>” into the “new.html.erb” to display the form. And BOOM! If you run rails you’ll see that it works completely fine & your code is looking clean!

Conclusion:

The main steps of our rails application are completed and working properly. If you followed this guide. You will have a pretty decent understanding of what’s going on in rails enough to build your own CRUD application. Though your application & code may not look completely like mine. Don’t worry and just have fun with it.