Advertisement
Ruby

Ruby on Rails from Scratch Week 3

by

Welcome to Ruby on Rails From Scratch Week 3! This week, we'll focus on specific things that you need to know about the framework. For example, we're going to talk about manipulating the structure of the project in two ways (rendering & redirecting). We'll also talk about how you add links in rails, and how to comment code. Let's get started already!

Catching Up

If you haven't read Parts 1 and 2, it is strongly advised that you review them before continuing on with this tutorial.

Adding Interactions Amongst Actions

Now that we've learned how to set instance variables to transfer information from the controller to the view, it is time to learn how to transmit data between different actions in a controller. For this tutorial, we're going to continue using the learn controller. We don't really need to keep what we did last week, but you can if you feel like it is a good resource.. We'll start off simple:

Perform Another Action in a different Action

For this example, the heading is more complex than the actual lesson. We are going to simply use what's in one action and do the same in another. Lets use the knowledge we gained last week about instance variables, and apply it now. First, let's create a new action called "another_action"; then another action called "text". We are going to then get the action from text and put it in "another_action". We are going to prove this, by referencing an instance variable in the view of "another_action" that was assigned in the "text" controller. Sorry, if that didn't make sense. If you didn't get what I just said, look at the following code, which will hopefully help you:

class LearnController < ApplicationController
    
  def another_action
  	text
  end

  def text
  	@text = 'This text came from another action'
  end
  end

We are then going to create a view called "another_action.html.erb", where we reference the variable text.

<html>
  <head>
  <title>Action Demo</title>
  </head>
<body>
    
  <%= @text %>
  </body>
  </html>

Explanation

As you can see, we referenced the action "text" simply by putting that inside of "another_action". By doing this, we also passed the definition of "text", which was the instance variable. To further demonstrate this principle, let's put this in several different situations, all of which work.

Situation 1- Setting An Instance Variable Equal to an Action

class LearnController < ApplicationController
	
	def another_action
		@text = text
	end
	
	def text
		misc_text = 'This text really traveled!'
	end	
end

Situation 1 Result

Text Travelled

Situation 2 - Replace Variable

Now we're going to get even more complex:

<html>
class LearnController < ApplicationController
	
	def another_action
		@text = "text you'll never see"
		@text = text
	end
	
	def text
		wanted_text = overwrite_view
	end
	
	def overwrite_view
		overwrite_text = 'This text overwrote the original text'
	end
end

Situation 2 Result

This is the order of events that the following code did:

  • Gave the instance variable "text" a value of "text you'll never see"
  • Then it re-assigned it to the action "text"
  • The variable "text", now has the value of the local variable wanted text.
  • The wanted_text variable has a value of the action "overwrite_view"
  • Overwrite_view has a local variable with a value of "This text overwrote the original text"
  • This carries back to the instance variable of @text.

Situation 3 Carry a Variable

We'll keep this one simpler:

class LearnController < ApplicationController
	
	def another_action
		@text = "text you'll never see"
		text
	end
	
	def text
		@text = 'This text overwrote the original text'
	end
end



Situation 3 Result

pass the variable

Situation 4 Returning Something Specific

class LearnController < ApplicationController
	
	def another_action
		@text = text
	end
	
	def text
		first = 'This text should not be passed to @text'
		second = 'This text would be put into the variable on default'
		return first
	end
		
end

This example is particularly important, as you are now learning a little bit more syntax; the return command. This will tell the action what to return at the end.

Situation 4 Result

return

Rails Links

Everyone should already know how to create a normal HTML link. (Using <a href="">Text</a>) But there's also a way to do it with Rails. This method is not Ruby, but rather a part of the framework. That being said, you can only use it in embedded ruby HTML files, not pure rb files. So how do we do it? Here is the code:

<html>
  <head>
  <title>Rails Link Demo</title>
  </head>
<body>
    
  <%= link_to('Another Action Link', :controller => 'learn', :action => 'another_action')%>
  </body>
  </html>

At first glance, you might wonder why you would ever change the way you write links, especially if the replacement is longer! Well one main reason is readability. You can easily read this and know exactly what it's going to link to. As for length, the :controller => part is not necessary if you're linking to an action within the same controller.

With this piece of rails code we are also seeing symbols. The ":controller =>" is a symbol. We'll talk more about what they do later, but for right now just recognize the colon.

Rendering in Rails

Earlier in this series, we talked a little bit about rails' sensible defaults. One of the defaults is to generate a view that has the same name as the action in the corresponding view. But what if we wanted to overwrite what rails automatically does? This is actually quite easy, and a very useful technique. When you're working on a real world project, you can imagine how 'clunky' your controller would get if you needed to create a separate view and action in the controller for each page. Rails has a solution though, which is called rendering. Rendering allows you to specify what view to use for each action. Keep in mind though, that like rails links, this is also rails exclusive code and not ruby, and meant only for the controller.

If the above has left you a little confused, let me show you how to do it. This will hopefully clarify it a little bit. For this first example, we're going to render the action to the view that it would normally render anyway. In other terms, this render code does nothing that wouldn't happen without it. All it is doing is showing some code that usually is just 'assumed'.

	def index
		render :action => 'index'
	end

Rendering an Action to another View

The last example isn't really useful since the result is achieved automatically anyway. But what if you had a really advanced view for another action, and you wanted the same view for a different action. It would not only be tedious to create another identical view for each action you create, but it would also be nearly impossible to update! All of that can be fixed though by rendering every similar action to a specific action. Examine the following piece of code which I will explain afterwards, and notice the different parts.

text_controller.rb:

class LearnController < ApplicationController
	
	def index
		render :action => 'text'
	end
	
	def text
		@text = '<u>Text</u>'
	end
	
	def other
		@text = '<b>Other</b>'
		render :action => 'text'
	end
		
end

text.html.erb:

<html>
  <head>
  <title>Rails Rendering Demo</title>
  </head>

<body> <p>Welcome to the <%= @text %> Page</p>

</body> </html>

Explanation of Code:

Index Action

You might have noticed that I included an action called "index". This action will be viewed if you go up a directory to "learn". It works like an ordinary index file would. You don't have to create a specific action for index though. You can use the previously covered topic of inheriting another action as well.

Rendering to the same view

For this example, we only needed one view for all of the actions; and they all produced different pages. To me, this is pretty incredible for the amount of work we put in.

Note: This might seem obvious to some, but beware of double rendering. Double rendering will cause an error because you're trying to render an action to two different places. Can you be in two places at once? No, and neither can an action. If you want to see what it looks like, just render an action to two different views. The reason it happens as you're doing more complex projects is because the trail of actions can get pretty complex, and you might accidentally create this error.

Make sure you get the basic concept of rendering, as it will be a very vital technique that you will use often as a rails developer.

Redirecting An Action

Redirecting an Action is similar to rendering an action in the fact that it too is rails code and only used in the controller. Also, it effects the flow of the application. As you might guess from the name, redirecting allows you to... well redirect.

You might be surprised by how many times you use the redirect command. Here are some common uses:

  • Creating alias pages
  • Performing an action in the controller and then redirecting to a secondary page
  • If there is an error, redirect to an error page
  • If user is not logged in, send them to a login page

Enough chit chat, let's get to the code! For this code example, we're just going to modify the last example's controller and leave the view the same. As you'll see, redirecting is very similar in format to rendering:

class LearnController < ApplicationController
	
	def index
		redirect_to :action => 'text'
	end
	
	def text
		@text = '<u>Text</u>'
		redirect_to :action => 'other'
	end
	
	def other
		render :action => 'text'
	end
		
end

Now go to the index action in your browser. You'll notice that you end up at the other action in your address bar. Let's run through this code:

  • First, we redirect to the action text. Like linking in rails, you can specify a controller too if you're redirecting to another controller. You would just put :controller => 'learn', before the action.
  • The browser now goes to the text action. Here it sets a value for @text. But the browser has no value for @text. This is because redirecting essentially forgets anything you tell it in that action.
  • We are now redirected to other. Here we render out to the text view.

Render or Redirect?

While there are some obvious scenarios where you would chose either to render or to redirect; there can be some harder decisions. One important key though is that if you're submitting data into a database or anything that is changing the application, use a redirect. Otherwise, a refresh could resubmit the data.

Final Thoughts

Hope you guys learned a lot from this week's tutorial! We covered a lot of important concepts so if you are still confused by anything, re-read it. Next week we'll probably get into ruby syntax!

As always, feel free to leave questions in the comments. Also, please digg this article if it helped you!

Related Posts
  • Code
    Theme Development
    Custom Controls in the Theme CustomizerTheme customizer custom control 400
    In the last article, we explored the advanced controls available in the Theme Customizer, and how to implement them. We’re going to look at how to create our own custom control, allowing you to choose which Category of Posts are displayed on the home page. To get started, download version 0.6.0 of our Theme Customizer Example.Read More…
  • Web Design
    UX
    Walk Users Through Your Website With Bootstrap TourTour retina
    When you have a web application which requires some getting used to from your users, a walkthrough of the interface is in order. Creating a walkthrough directly on top of the interface makes things very clear, so that's what we're going to build, using Bootstrap Tour.Read More…
  • Code
    Ruby
    Writing Robust Web Applications - The Lost Art of Exception HandlingRails education retina preview2
    As developers, we want the applications we build to be resilient when it comes to failure, but how do you achieve this goal? If you believe the hype, micro-services and a clever communication protocol are the answer to all your problems, or maybe automatic DNS failover. While that kind of stuff has its place and makes for an interesting conference presentation, the somewhat less glamorous truth is that making a robust application begins with your code. But, even well designed and well tested applications are often lacking a vital component of resilient code - exception handling.Read More…
  • Code
    Ruby
    Using New Relic Custom Metrics to Monitor All the ThingsGetting started new relic retina preview2
    When you first get introduced to New Relic, it's easy to be overwhelmed by all the features. But like with most tools, as you slowly climb the learning curve and get familiar with the features provided out of the box, you begin to wonder how it all hangs together under the hood and if there is more you can do with what you have at hand.Read More…
  • Code
    Scala
    Building Ribbit in ScalaRibbit scala retina preview
    In this tutorial we will implement the Ribbit application in Scala. We'll be covering how to install the Play web framework, a NetBeans plugin for it, and finally the code in Scala. If you are new to Scala, check out this previous tutorial which will help you set up your environment and provides you with a general platform that you can build upon. Even though the essence of Ribbit is to create/send/read Ribbits (our version of tweets), we will spend a large part of this tutorial explaining how Play works, authentication, and persistence. After these are in place, the rest becomes much easier. We will also implement ribbit creation, submission and listing out all ribbits. Following someone, advanced user settings, and direct messages will be an extra assignment for you to complete on your own. I am sure if you manage to follow along with this tutorial and create Ribbit as explained below, these three functionalities will be easily accomplished as homework.Read More…
  • Code
    Ruby
    Digging Into Rails 4Digging rails
    Rails 4 is rapidly approaching. In this article, let's take a look at some of the new features that it offers, as well as the changes that may affect your current applications.Read More…