How to Write a Ruby on Rails App for STEEM

Rails is a common development framework used by many hobbyists and professionals for rapid web development. It is ideal for smaller projects, but has been used in large deployments like (don't laugh) Yellow Pages.

This tutorial assumes you know how to install rails. We're assuming Rails 4 or 5 (but you might luck out on Rails 3). If you don't have the rails command, here's how to get started:

https://gorails.com/setup

I'm going to skip most of the best practices. We're not going to create unit tests or rspec, for instance. This will be a bare minimum app. So once you've installed rails and are up and running, let's create our app.

$ rails new steemapp
$ cd steemapp
$ rails generate controller accounts show --no-helper --no-assets --no-test-framework
$ rails generate controller followers index --no-helper --no-assets --no-test-framework

Edit config/routes.rb:

get 'followers/index'

get 'accounts/show'

... and replace it with:

resources :accounts, only: :show do
  resources :followers, only: :index
end

... so it becomes:

Edit Gemfile and add the following gems:

gem 'radiator', github: 'inertia186/radiator'

Optional: Add this as well to Gemfile if you want helpful debug messages:

group :development do
  gem 'better_errors'
  gem 'binding_of_caller'
end

Now install radiator any everything else in Gemfile:

$ bundle install
$ bundle update

Edit app/controllers/application_controller.rb and add:

helper_method :api, :follow_api

Also, add the private methods to the same file:

private
  def api
    @@API ||= Radiator::Api.new
  end

  def follow_api
    @@FOLLOW_API ||= Radiator::FollowApi.new
  end

... so it becomes:

Edit app/controllers/accounts_controller.rb and add an action:

def show
  @account = api.get_accounts([params[:id]])
  
  if !!@account.result
    @account = @account.result.first
  end
end

... so it becomes:

Edit app/views/accounts/show.html.erb:

<h1>Account: <%= params[:id] %></h1>

<p>
  <strong>Created:</strong>
  <%= time_ago_in_words Time.parse(@account.created) %>
</p>

<p>
  <strong>Last Vote:</strong>
  <%= time_ago_in_words Time.parse(@account.last_vote_time) %>
</p>

<p>
  <strong>Last Post:</strong>
  <%= time_ago_in_words Time.parse(@account.last_root_post) %>
</p>

<p>
  <strong>Last Comment:</strong>
  <%= time_ago_in_words Time.parse(@account.last_post) %>
</p>

<p>
  <strong>STEEM Balance:</strong>
  <%= @account.balance %>
</p>

<p>
  <strong>SBD Balance:</strong>
  <%= @account.sbd_balance %>
</p>

<p>
  <strong>Witness Votes:</strong>
  <%= @account.witness_votes.to_sentence %>
</p>

<%= link_to 'Followers', account_followers_path(params[:id]) %>

Edit app/controllers/followers_controller.rb and add an action:

def index
  @account_id = params[:account_id].to_s.gsub(',', '.')
  @after = (params[:after] || 0)
  per_page = @after == 0 ? 25 : 26

  @followers = follow_api.get_followers(@account_id, @after, 'blog', per_page)

  @followers = if !!@followers.result
    @followers = @followers.result.map(&:follower) - [@after]
  end
end

... so it becomes:

Edit app/views/followers/index.html.erb:

<h1>Account: <%= params[:account_id] %></h1>

<ul>
  <% @followers.each do |follower| %>
  <li /> <%= link_to follower, account_followers_path(account_id: follower.gsub('.', ',')) %>
  <% end %>
</ul>

[
<%= link_to "Previous", :back %>
|
<%= link_to "Next", account_followers_path(account_id: @account_id, after: @followers.last) %>
]

Now start the server:

$ rails server

Now browse to:

http://localhost:3000/accounts/ned


Troubleshooting

When trying out the app for the first time, going to the accounts page works, but going to followers has the following error:

undefined method `each' for nil:NilClass

This is actually a problem with the public api. The default api we're using is this.piston.rocks. Sometimes it doesn't respond to follow_api requests.

One solution is to just wait and try again later.

Another solution is to point at a different api by modifying app/controllers/application_controller.rb

Radiator::FollowApi.new(url: 'http://my.fancy.api:443')

Special thanks to @arrowj for testing out the tutorial. He risked and received headaches to make sure the steps are correct. I highly recommend following his blog.

H2
H3
H4
3 columns
2 columns
1 column
5 Comments