Reputation: 155
So my code in my overview.html.erb looks like this.
<h1>Socialapi Overview</h1>
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Facebook ID</th>
<th>Facebook Likes</th>
<th>Behance Follower</th>
<th>Instagram Follower</th>
<th>Pinterest Follower</th>
<th>Twitter Follower</th>
<th>Social Reach</th>
</tr>
</thead>
<tbody>
<% @artists.each do |artist| %>
<tr>
<td><%= artist.name %></td>
<td><%= facebook_id(artist.facebook) %></td>
<td><%= fb_likes = facebook_likes(artist.facebook) %></td>
<td><%= behance(artist.behance) %></td>
<td><%= instagram = instagram(artist.instagram) %></td>
<td><%= pinterest = pinterest(artist.pinterest) %></td>
<td><%= twitter = twitter(artist.twitter) %></td>
<td><%= social_reach(fb_likes,instagram,twitter,pinterest) %></td>
</tr>
<% end %>
</tbody>
</table>
the Controller:
class SocialapiController < ApplicationController
before_action :authenticate_admin!
def overview
@artists = Artist.all
end
end
and my helpers:
module ApplicationHelper
def social_reach(facebook_likes,instagram_follower,twitter_follower,pinterest_follower)
social_reach = (facebook_likes.to_i*0.7)+(instagram_follower.to_i*0.05)+(twitter_follower.to_i*0.15)+(pinterest_follower.to_i*0.1)
return social_reach
end
def facebook_id(facebook_name)
graph = Koala::Facebook::API.new
begin
facebook_id = graph.get_object(facebook_name)["id"]
rescue Exception => exc
logger.error("Message for the log file #{exc.message}")
facebook_id = "fb_name is not correct"
end
return facebook_id
end
def facebook_likes(facebook_name)
graph = Koala::Facebook::API.new
begin
facebook_likes = graph.get_object(facebook_name)["likes"]
rescue Exception => exc
logger.error("Message for the log file #{exc.message}")
facebook_id = "fb_name is not correct"
end
return facebook_likes
end
def instagram(instagram_name)
instagram_client = Instagram.client(access_token: "#######")
Instagram.configure do |config|
config.client_id = "####"
config.client_secret = "####"
# For secured endpoints only
#config.client_ips = '<Comma separated list of IPs>'
end
begin
for user in instagram_client.user_search("#{instagram_name}")
instagram_follower = instagram_client.user_followed_by(user.id).count
end
rescue Exception => exc
logger.error("Message for log file #{exc.message}")
instagram_follower = "instagram profile is private"
end
return instagram_follower
end
def twitter(twitter_name)
twitter_client = Twitter::REST::Client.new do |config|
config.consumer_key = "###"
config.consumer_secret = "###"
config.access_token = "###"
config.access_token_secret = "###"
end
begin
twitter_follower = twitter_client.user(twitter_name).followers_count
rescue Exception => exc
logger.error("Message for the log file #{exc.message}")
twitter_follower = "twitter name is not correct"
end
return twitter_follower
end
def behance(behance_name)
behance_client = Behance::Client.new(access_token: "###")
begin
behance_follower = behance_client.user(behance_name)["stats"]["followers"]
rescue Exception => exc
logger.error("Message for the log file #{exc.message}")
behance_follower = "behance name is not correct"
end
return behance_follower
end
def pinterest(pinterest_name)
begin
require 'open-uri'
url = "http://www.pinterest.com/#{pinterest_name}/followers/"
doc = Nokogiri::HTML(open(url))
pinterest_follower = doc.css(".FollowerCount").text
pinterest_follower ["Followers"] = ""
if pinterest_follower.include? ","
pinterest_follower [","] = ""
end
rescue Exception => exc
logger.error("Message for log file #{exc.message}")
pinterest_follower = "pinterest name is not correct"
end
return pinterest_follower
end
end
This tool delivers some "live" data that I get with my application_helpers and with some gems.
First I want to know if this is the right way to make methods that I use in several controllers? I' new to RoR so please give me some advice if I did s.th. wrong.
Second ... now I want to boost my performance. I think multithreading could be one option, am I right?
So where exactly do I do this? in the controller and how does this work?
thanks, I thankful for any help.
best Stefan
Upvotes: 0
Views: 137
Reputation: 211560
You've got the right idea here, helpers are a good place to put code that's shared amongst different views, but it's not exactly optimal. My biggest concern here is how much application code you have in your helper, a place that can be more difficult to test than if it were exposed another way, like as a Rails concern module instead.
You're going to have a lot of trouble getting this page to load in reasonable time with so many external dependencies. Each of those method calls is going to take an unpredictable amount of time to execute, where that time could be anything from zero seconds to two minutes. That's unacceptable.
Instead, queue up a job to retrieve that information and populate it in a database table of some sort. Postgres has a fast native JSON data type that is great for storing "whatever" type data. There's also a number of background-job solutions for Rails to delegate this to.
Here's an example method of yours that bucks the traditional Ruby style re-written to be more conventional:
require 'open-air'
# ^ Generally dependencies go at the top of the file, not buried inside methods.
def pinterest(pinterest_name)
url = "http://www.pinterest.com/#{pinterest_name}/followers/"
doc = Nokogiri::HTML(open(url))
pinterest_follower = doc.css(".FollowerCount").text
pinterest_follower["Followers"] = ""
# ^ No space between variables and method calls like () or []
pinterest_follower.gsub!(/,/, '')
# ^ Rewritten as an in-place modification to remove the commas
rescue Exception => exc
# ^ A rescue can exist at the same level as a method definition, avoiding
# the need for a begin/end block around it.
logger.error("Message for log file #{exc.message}")
pinterest_follower = "pinterest name is not correct"
ensure
# ^ The ensure block is always run regardless of exceptions.
pinterest_follower
# ^ return is not necessary unless you're exiting the method early.
end
As for performance, the general pattern in Rails is to approach issues in the following priority:
includes
on your models when loading them.pluck
.Update: Expanded on Michal's observations.
Upvotes: 1