Sean Magyar
Sean Magyar

Reputation: 2380

rails invoking methods controller vs model

I've got a rails app. I'm trying to finetune different models and controllers. I can make the things work, but I'm not sure if I'm doing the preferred way. So I have an event.rb for my own in-app fullcalendar where I can CRUD new events and have social.rb for omniauth authorization (google calendar in this case). I'm trying to display the gcal events in my fullcalendar, so based on the social.rb data (tokens, keys) I make an API call to google to get gcal event times and then display the data in events/index page (fullcalendar).

Here are two of my methods I don't know how/where to put in my app. My questions (I have 3 as they are closely connected):

events_controller

  def index
    @user = current_user
    @google = @user.socials.where(provider: "google_oauth2").first
    @client = Social.init_google_api_calendar_client(@google) ### Is this the proper way to call this method?
    @get_busy_times = #####how to call the get_buys_events method?
    @event = Event.new
    @events = Event.allevents(current_user)
    respond_to do |format|
      format.html
      format.json { render json: @events }
      format.js
    end
  end

social.rb

  def self.init_google_api_calendar_client(google_account)
    #method only called if google_oauth2 social exists
    client = Google::APIClient.new
    client.authorization.access_token = google_account.token
    client.authorization.client_id = ENV['GOOGLE_API_KEY']
    client.authorization.client_secret = ENV['GOOGLE_API_SECRET']
    client.authorization.refresh_token = google_account.refresh_token
    return client
  end

Where to put this method? Should be class/instance? How should be invoked?

  def get_busy_events(client)
    service = client.discovered_api('calendar', 'v3')
    result = client.execute(
      api_method: service.freebusy.query,
      body_object: { timeMin: start_at,
                     timeMax: end_at,
                     items: items},
      headers: {'Content-Type' => 'application/json'})
  end

Upvotes: 1

Views: 273

Answers (1)

Sean Huber
Sean Huber

Reputation: 3985

You're asking a good question and in my experience there isn't a universally adopted convention in the Rails community for where to put code that makes server-side API calls to 3rd party services.

When your app uses external APIs in ways that are okay to be asynchronous, it would be appropriate to invoke these calls using ActiveJob or gems like sidekiq directly. Here's a decent write-up (see the section labeled "Talking with external APIs"): https://blog.codeship.com/how-to-use-rails-active-job/

But, if you are building an app that truly dependent on the 3rd-party API and asynchronous calls don't provide you much benefit, then I suggest defining a different type of class that is neither a model, view, nor controller. A common practice to follow when there aren't already gems to meet your needs is to write a ruby wrapper class for the API saved under the lib folder. Keep your model methods scoped towards logic that requires database interactivity. Invoke model methods from your controller as well as webservice methods defined in your wrapper class.

Good luck!

Upvotes: 2

Related Questions