2

I have a basic twitter api app in rails, which works perfectally locally, however when I pushed to Heroku it doesn't work and upon checking the logs there is an error saying uninitialized constant WelcomeController::TwitterApi. I can not find out how to rectify this. Many thanks.

lib/twitter_api.rb

class TwitterApi
  def initialize(user)
    @user = user
  end

  def our_public_tweets
    client.user_timeline(user, count: 1, exclude_replies: true, include_rts: false)
  end

  def followers
    client.followers.take(20)
  end

  private

  attr_reader :user

  def client
    @client ||= Twitter::REST::Client.new do |config|
      config.consumer_key = Rails.application.secrets.twitter_api_key
      config.consumer_secret = Rails.application.secrets.twitter_api_secret
      config.access_token = user.token
      config.access_token_secret = user.secret
    end
  end
end

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end

  # to enable the current_user variable to be used in the view file
  helper_method :current_user

end

welcome_controller.rb

class WelcomeController < ApplicationController
  def index
    @twitter_api = TwitterApi.new(current_user)
  end
end

views/welcome/index.html.erb

<div class="wrapper">
  <h1>OMNIAUTH AND TWITTER API</h1>

  <!-- <%= link_to "Sign in with Twitter", "/auth/twitter" %> -->
  <% if current_user %>
    <div id="sign_in_wrapper">
      <p id="sign_in">Signed in as <span><%= current_user.name %></span> </p>
      <%= image_tag current_user.profile_image, class: "profile_image" %>
      <p><%= link_to "Sign out", signout_path, id: "sign_out" %></p>
    </div>

    <div class="public_tweets">
      <p>Latest tweet from <%= current_user.name %>:</p>
      <% @twitter_api.our_public_tweets.each do |tweet| %>
        <% cache('our_public_tweets', expires_in: 6.hours) do %>
          <%= parsed_tweet(tweet) %>
        <% end %>
      <% end %>
    </div>

    <ul class="followers">
      <p>First 20 followers for <%= current_user.name %>:</p>
      <% @twitter_api.followers.each do |follower| %>
        <% cache('followers', expires_in: 6.hours) do %>
          <li><%= follower.name %></li>
          <hr>
        <% end %>
      <% end %>
    </ul>

  <% else %>

    <%= link_to "/auth/twitter", id: "link_button" do %>
      <i class="fa fa-twitter fa-3x"></i>
    <% end %>
    <p class="date">Click the twitter icon to sign in and view followers</p>

  <% end %>
</div>

models/user.rb

class User < ApplicationRecord
  def self.from_omniauth(auth_hash)
    #Look up the user or create them using keys in the auth hash
    user = where(provider: auth_hash.provider, uid: auth_hash.uid).first_or_create
    user.update(
      name: auth_hash.info.name,
      profile_image: auth_hash.info.image,
      twitter_user_name: auth_hash.info.nickname,
      token: auth_hash.credentials.token,
      secret: auth_hash.credentials.secret
    )
    user
  end

  # token and secret is what came back from omniauth and this was saved to the user database.
end

application_helper.rb

module ApplicationHelper

  def parsed_tweet(tweet)
    _parsed_tweet = tweet.text.dup

    tweet.urls.each do |entity|
      html_link = link_to(entity.display_url.to_s, entity.expanded_url.to_s, target: 'blank')
      _parsed_tweet.sub!(entity.url.to_s, html_link)
    end

    tweet.media.each do |entity|
      html_link = link_to(entity.display_url.to_s, entity.expanded_url.to_s, target: 'blank')
      _parsed_tweet.sub!(entity.url.to_s, html_link)
    end

    _parsed_tweet.html_safe
  end
end
sdawes
  • 631
  • 1
  • 7
  • 15

1 Answers1

2

It looks like you are not auto loading the classes in you controller. You could try adding require 'twitter_api' to your welcome controller

C dot StrifeVII
  • 1,885
  • 1
  • 16
  • 21
  • Im afraid that doesnt work, it then comes up with an error when pushing to heroku `can't modify frozen Array` and `Push rejected, failed to compile Ruby app.` Does it matter that I already have the line you suggested, but written in the config/application.rb file, under the module RailsTwitterApi? – sdawes Oct 15 '16 at 17:33
  • 1
    If you already have it there then this is not the issue. You could try adding `require 'twitter_api'` to your welcome controller – C dot StrifeVII Oct 15 '16 at 17:37
  • That did it! Simple as! Thanks for that! Just for my understanding, why does this need it for heroku but it works fine locally? Cheers! – sdawes Oct 15 '16 at 17:40
  • So the short answer is I don't know. The long guess is something to do with how heroku loads the lib directory. Its possible that the line in your application.rb is not doing what we think I would have to see the whole app to figure it out. I will also update the answer I gave. Glad I could help. – C dot StrifeVII Oct 15 '16 at 17:45
  • Cheers for your help! I don't suppose you know why heroku is only displaying the first follower I have, but 20 times, whereas locally it actually displayed the first 20 followers lol. – sdawes Oct 16 '16 at 10:07
  • I would log into the console and make sure that heroku's database does not have 20 of the same user. It is possible the cache is not working as expected as well. – C dot StrifeVII Oct 16 '16 at 12:53
  • @sdawes did you ever figure out the rest of the issue? – C dot StrifeVII Oct 19 '16 at 19:48