mhaliski
mhaliski

Reputation: 95

Rails: Persist the client from Twitter gem by sferik

I'm using the Twitter gem and Devise/Omniauth to perform actions on a user's behalf. Everything is going smoothly and I can successfully tweet for folks. However, something feels icky.

How are you guys persisting the Twitter client? I.e.

client = Twitter::REST::Client.new do |config|
    config.consumer_key = Rails.application.secrets.twitter_consumer_key
    config.consumer_secret = Rails.application.secrets.twitter_consumer_secret
    config.access_token = 'xxxx'
    config.access_token_secret = 'xxxx'
end

It doesn't make sense in my brain to instantiate the client before every subsequent API call. Twitter, as you know, will rate limit you after a while.

So, what's the best way to persist 'client' throughout a session?

Upvotes: 0

Views: 265

Answers (2)

rakeshpatra
rakeshpatra

Reputation: 761

While initialising Twitter client in initializer its better to not include the access token and the access secret token in the initializer since this value will vary from user to user .And when initialising it to any local /instance variables try to use TWITTERCLIENT.dup because it will create a different object ID for your instance,if you will use the same constant then any change to the instance variables will be affect the constant .

Upvotes: 0

Robert Nubel
Robert Nubel

Reputation: 7532

Actually, instantiating the client 100 times doesn't involve any more communication with Twitter than instantiating it once; it's the actual use of the client that invokes the network traffic and thus matters. But, you're not wrong that there's no real reason to re-instantiate it each time. You have a couple options, depending on your use case:

  • Use a Rails initializer. That is, you can build your client instance in config/initializers/twitter.rb and assign it to something globally-accessible, like a constant (TwitterClient = Twitter::REST::Client.new do ...). This is only okay if your configuration is never changed unless you redeploy the app, and -- importantly -- if the Twitter client is thread-safe. That's often not a valid assumption for Ruby gems, but if you're running on MRI, you probably don't need to worry about it.
  • Inside whatever object you use the twitter client, cache the instance. The easiest way to do this is like so:

    def twitter_client
      @twitter_client ||= Twitter::REST::Client.new do ...
    end
    
    # ...
    
    def other_method
      twitter_client.do_something(foo: "bar")
    end
    

    However, your mileage may vary -- instance-variable caching only sticks around as long as the object does, which for a controller is only during one request. You could also cache it into a class variable, but that's effectively the same as the first option, above.

Ultimately, instantiating Ruby objects is pretty cheap, so I wouldn't worry too much about it. Trying to avoid instantiating objects often ends you up wasting more of your time in development than you'll actually save in production (as with most premature optimizations).

Upvotes: 1

Related Questions