When I first started learning Rails, one of the patterns that I thought was pure 'magic' was how you could access a controller's instance variables in the views.

# controllers/posts_controller.rb
class PostsController
  def show
    @post = Post.find(1)
  end
end

# views/posts/show.html.erb
<%= @post.title %>

For a long time, I didn't understand how this would work behind the scenes. I tried reading the source code a few times without success. I just wasn't familiar enough with Ruby's advanced metaprogramming techniques.

If you're feeling the same, worry not. In this lesson, we'll learn one way to implement the Rails views pattern, where a controller's instance variables are accessible in the view, in pure Ruby.

This lesson won't show how Rails actually implements the views behind the scenes. I'm only trying to mimic the external Rails API, i.e. making controller instance variables available in views.

In the appendix, we'll learn how Rails views work. However, I still wanted to show what a simplest views implementation could look like, to de-mystify some of the magic and give an intuitive understanding of the data handover from controllers to views.

Alright, enough rambling. Let's get started.

As things stand now, our controllers are returning a plain text response from the index action method. The router calls the controller's action to get this plain text response and returns it to the browser.

require_relative 'application_controller'

class ArticlesController < ApplicationController
  def index
    index_file = File.join(Dir.pwd, "views", "index.html")
    File.read(index_file)
  end
end

To make it behave like Rails, we'll want to assign the data required by a view to an instance variable:

require_relative 'application_controller'

class ArticlesController < ApplicationController
  def index
    @title = "Write Software, Well"
    @tagline = "Learn to program Ruby and build webapps with Rails"
  end
end

Then, the instance variables @title and @tagline will be used by the corresponding view, just like Rails.

<%# views/articles/index.html.erb %> 

<header>
  <h1>
    <%= @title %>
  </h1>
  <p>
    <%= @tagline %>
  </p>
</header>

Let's see how we can implement this in the next lesson.