Search code examples
ruby-on-railsmodeldrylinkedin-api

How can I make DRY repeated code used in model methods and in controllers in Rails 3?


I have the following methods for a single model, and may have more. I may also have some of the repeated code in a helper. How can I make it DRY?

25   def full_name
 26     client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
 27     client.authorize_from_access(self.atoken, self.asecret)
 28     client.profile(id => self.uid)
 29     client.profile.first_name + " " + client.profile.last_name
 30   end
 31 
 32   def image_url
 33     client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
 34     client.authorize_from_access(self.atoken, self.asecret)
 35     client.profile(id => self.uid)
 36     client.profile(:fields => "picture-url").picture_url
 37   end

The code where I instantiate the client and access the profile id for the most part is repeated everytime I need to make a method call on the API. It's just the API that changes.

What happens when I also need to call in the controller (of a different model?)

29     if @review.save
 30       flash[:notice] = "Successfully created review."
 31       # check if allowed to post to LinkedIn and post
 32       if @review.post_linkedin?
 33         client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
 34         client.authorize_from_access(current_user.atoken, current_user.asecret)
 35         debugger 
 36         client.update_network("has shared expertise on <a")
 37       end

How could I make it more dry?


Solution

  • I would add the following methods to your user class:

    class User
      def linkedin_client
        @linkedin_client || = get_linkedin_client 
      end
    
      def linkedin_profile
        linkedin_client.profile(id => self.uid)
        linkedin_client.profile
      end
    
      def full_name
        linkedin_profile.first_name + " " + user.linkedin_profile.last_name
      end
    
      def image_url
        linkedin_profile(:fields => "picture-url").picture_url
      end
    
    
      private
    
      def get_linkedin_client
        client = LinkedIn::Client.new(ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'])
        client.authorize_from_access(atoken, asecret)   
        client     
      end
    end
    

    and inside your controller you would write:

    if @review.save
      flash[:notice] = "Successfully created review."
      # check if allowed to post to LinkedIn and post
      if @review.post_linkedin?
        current_user.linkedin_client.update_network("has shared expertise on <a")
      end
    end
    

    Hope this helps.