在rails控制器中调用ruby方法会引发错误

时间:2015-12-31 00:19:34

标签: ruby-on-rails ruby methods

我有一个rails应用程序,我正在尝试从控制器调用以下方法,但是我收到此错误:

undefined local variable or method "service" for #<EventsController:0x007fb6d27da1c8>` for this line: `api_method: service.freebusy.query

这里有什么问题?为什么get_busy_events无法在服务变量上面定义它?

  

控制器

include GoogleCalendarApi
.....
@user = current_user
@google = @user.socials.where(provider: "google_oauth2").first
unless @google.blank?
  @client = init_google_api_calendar_client(@google)
  @result = open_gcal_connection(get_busy_events, @client, @google)
  

LIB / google_api_calendar.rb

def 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

def open_gcal_connection(options, initialized_client, social_object)
  client = initialized_client
  old_token = client.authorization.access_token
  service = client.discovered_api('calendar', 'v3')
  result = client.execute(options) #after execution you may get new token

  # update token if the token that was sent back is expired
  new_token = client.authorization.access_token
  if old_token != new_token
    social_object.update_attribute(token: new_token)
  end
  return result
end

def get_busy_events
  result = open_gcal_connection(
    api_method: service.freebusy.query,
    body: JSON.dump({ timeMin: '2015-12-24T17:06:02.000Z',
                   timeMax: '2013-12-31T17:06:02.000Z',
                   items: social_object.email }),
    headers: {'Content-Type' => 'application/json'})
  #handling results
end

1 个答案:

答案 0 :(得分:1)

回答你的问题(正如我在评论中所做的那样):

要修复方法,您必须在调用它的操作中定义service变量。

至于您发布的链接:如果您查看get_busy_events方法,则有一行service = client.discovered_api('calendar', 'v3')

它很好,因为它在方法中。 client声明所依赖的service也是如此 - 您必须在使用它们的方法中声明它们。

你应该按照文章的说法制作代码,这样你就可以了:

def init_client
  client = Google::APIClient.new
  # Fill client with all needed data
  client.authorization.access_token = @token #token is taken from auth table
  client.authorization.client_id = @oauth2_key
  client.authorization.client_secret = @oauth2_secret
  client.authorization.refresh_token = @refresh_token
  return client
end

可用于在所有其他操作中定义client变量,然后使用service方法:

def get_busy_times
  client = init_client
  service = client.discovered_api('calendar', 'v3')
  @result = client.execute(
    :api_method => service.freebusy.query,
    :body_object => { :timeMin => start_time, #example: DateTime.now - 1.month
                      :timeMax => end_time, #example: DateTime.now + 1.month
                      :items => items
                    },
    :headers => {'Content-Type' => 'application/json'}})
end

编辑No2:

由于您有一个控制器,客户端初始化,我建议将其作为参数传递:

include GoogleCalendarApi
.....
@user = current_user
@google = @user.socials.where(provider: "google_oauth2").first
unless @google.blank?
  @client = init_google_api_calendar_client(@google)
  @result = open_gcal_connection(get_busy_events(@client), @client, @google)

并更改get_busy_events方法:

def get_busy_events(client)
  service = client.discovered_api('calendar', 'v3')
  result = open_gcal_connection(
    api_method: service.freebusy.query,
    body: JSON.dump({ timeMin: '2015-12-24T17:06:02.000Z',
                   timeMax: '2013-12-31T17:06:02.000Z',
                   items: social_object.email }),
    headers: {'Content-Type' => 'application/json'})
  #handling results
end

虽然这对我来说有点奇怪(像这样嵌套参数)所以你应该看看重构这个。