Ruby on rails 在另一个Ruby方法中访问局部变量
我希望了解如何访问方法a中的变量集,然后在方法B中使用该变量,以及如何以干净的方式重用代码的相同部分,然后只更改查询Ruby on rails 在另一个Ruby方法中访问局部变量,ruby-on-rails,ruby,ruby-on-rails-4,methods,google-api,Ruby On Rails,Ruby,Ruby On Rails 4,Methods,Google Api,我希望了解如何访问方法a中的变量集,然后在方法B中使用该变量,以及如何以干净的方式重用代码的相同部分,然后只更改查询 require 'google/api_client' module GoogleAnalytics class Analytic SERVICE_ACCOUNT_EMAIL_ADDRESS = ENV['SERVICE_ACCOUNT_EMAIL_ADDRESS'] PATH_TO_KEY_FILE = ENV['PATH_TO_KEY_FI
require 'google/api_client'
module GoogleAnalytics
class Analytic
SERVICE_ACCOUNT_EMAIL_ADDRESS = ENV['SERVICE_ACCOUNT_EMAIL_ADDRESS']
PATH_TO_KEY_FILE = ENV['PATH_TO_KEY_FILE']
PROFILE = ENV['ANALYTICS_PROFILE_ID']
def google_analytics_api
client = Google::APIClient.new(
application_name: "Example Application",
application_version: "1.0")
client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => 'https://www.googleapis.com/auth/analytics.readonly',
:issuer => SERVICE_ACCOUNT_EMAIL_ADDRESS,
:signing_key => Google::APIClient::KeyUtils.load_from_pkcs12(PATH_TO_KEY_FILE, 'notasecret')).tap { |auth| auth.fetch_access_token! }
api_method = client.discovered_api('analytics','v3').data.ga.get
# make queries
result = client.execute(:api_method => api_method, :parameters => {
'ids' => PROFILE,
'start-date' => Date.new(2014,1,1).to_s,
'end-date' => Date.today.to_s,
'dimensions' => 'ga:pagePath',
'metrics' => 'ga:pageviews',
'filters' => 'ga:pagePath==/'
})
end
end
end
因此,如果我运行google_analytics_api方法,我会得到一组分配给变量result的返回结果
那么,如果我想要另外两个单独的方法,它们将返回不同的结果集,那么
新用户和跳出率,这将是两个不同的调用更改请求参数,不是吗?我需要重复整个方法吗
有没有办法重构它,这样授权调用就可以封装在它的on方法中,我所做的更改就是将请求参数分配给result
像这样的
def api_call
logic to make request
end
def new_users
api_call
# make queries
result = client.execute(:api_method => api_method, :parameters => {
'ids' => PROFILE,
'start-date' => Date.new(2014,1,1).to_s,
'end-date' => Date.today.to_s,
'dimensions' => 'ga:pagePath',
'metrics' => 'ga:newUsers',
'filters' => 'ga:pagePath==/'
})
end
尽管其中一个问题是,在新的_users方法中可以使用局部变量客户机和结果,但这些可以更改为什么?带有@的实例变量?或者是一个带有@@?的类变量,你的直觉很好-你自己,而且有更好的方法来构造这段代码。但与其共享变量,不如考虑松散连接的小块。写一个能很好地完成一件事的方法,并将它们结合在一起。例如,我们可以编写一个
get_client
方法,该方法只返回一个client
,供其他方法使用:
protected
def get_client
client = Google::APIClient.new(
application_name: "Example Application",
application_version: "1.0")
client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => 'https://www.googleapis.com/auth/analytics.readonly',
:issuer => SERVICE_ACCOUNT_EMAIL_ADDRESS,
:signing_key => Google::APIClient::KeyUtils.load_from_pkcs12(PATH_TO_KEY_FILE, 'notasecret')).tap { |auth| auth.fetch_access_token! }
client
end
它受到保护
,因为外部代码-你的分析类之外的东西-不应该直接使用它。他们应该使用我们为他们提供的方法
您还可以提供一个助手方法来从API获取结果。我不熟悉查询API,但看起来是您的度量值改变了。所以可能是这样的:
protected
def get_result(metrics)
client = self.get_client
api_method = client.discovered_api('analytics','v3').data.ga.get
result = client.execute(:api_method => api_method, :parameters => {
'ids' => PROFILE,
'start-date' => Date.new(2014,1,1).to_s,
'end-date' => Date.today.to_s,
'dimensions' => 'ga:pagePath',
'metrics' => metrics,
'filters' => 'ga:pagePath==/'
})
result
end
现在,您可以编写外部类可以使用的简单方法:
def new_users
get_result('ga:newUsers')
end
def total_visits
get_result('ga:pageViews')
end
如果可以,尝试从这些方法返回简单数据。也许total_visions
将返回get_result('ga:pageViews')['totalsForAllResults']['ga:pageViews']
。类外的代码不必知道GA数据格式就可以使用它。这就是所谓的。你的直觉是好的-你,而且有更好的方法来构建这段代码。但与其共享变量,不如考虑松散连接的小块。写一个能很好地完成一件事的方法,并将它们结合在一起。例如,我们可以编写一个get_client
方法,该方法只返回一个client
,供其他方法使用:
protected
def get_client
client = Google::APIClient.new(
application_name: "Example Application",
application_version: "1.0")
client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => 'https://www.googleapis.com/auth/analytics.readonly',
:issuer => SERVICE_ACCOUNT_EMAIL_ADDRESS,
:signing_key => Google::APIClient::KeyUtils.load_from_pkcs12(PATH_TO_KEY_FILE, 'notasecret')).tap { |auth| auth.fetch_access_token! }
client
end
它受到保护
,因为外部代码-你的分析类之外的东西-不应该直接使用它。他们应该使用我们为他们提供的方法
您还可以提供一个助手方法来从API获取结果。我不熟悉查询API,但看起来是您的度量值改变了。所以可能是这样的:
protected
def get_result(metrics)
client = self.get_client
api_method = client.discovered_api('analytics','v3').data.ga.get
result = client.execute(:api_method => api_method, :parameters => {
'ids' => PROFILE,
'start-date' => Date.new(2014,1,1).to_s,
'end-date' => Date.today.to_s,
'dimensions' => 'ga:pagePath',
'metrics' => metrics,
'filters' => 'ga:pagePath==/'
})
result
end
现在,您可以编写外部类可以使用的简单方法:
def new_users
get_result('ga:newUsers')
end
def total_visits
get_result('ga:pageViews')
end
如果可以,尝试从这些方法返回简单数据。也许total_visions
将返回get_result('ga:pageViews')['totalsForAllResults']['ga:pageViews']
。类外的代码不必知道GA数据格式就可以使用它。这就是所谓的。通过在Skype上的交谈,我认为有几件事需要考虑
Init
目前,每当您想使用该模块时,您都在使用google\u analytics\u api
方法。这是完全没有效率的,这也是你现在有这个问题的部分原因。相反,我将创建一个init
方法,它将在每次启动时启动(并将GoogleAnalytics
生成一个自己的类):
这将允许您将当前模块视为真正的Ruby对象-如下所示:
@analytics = GoogleAnalytics.new #-> fires initialize method
这将使您能够调用对象(它将从API中提取数据),然后根据您拥有的不同用例相应地分割数据
实例方法
这使我很好地理解了实例方法的概念
您所指的,实际上也是Alex p所指的,是实例方法的思想。它兼作对象的属性,但本质上允许您在方法实例上调用一段功能
在Alex的例子中,你有:
def new_users
get_result('ga:newUsers')
end
这只是调用类的实例方法:
GoogleAnalytics::Analytic.new_users
这将创建一个analysis
类的实例,然后调用new\u users
方法(应该是一个实例)。然后,此方法将允许您对新初始化的对象调用实例
方法,从而调用获取结果
方法
--
我的建议是在对象初始化后使用实例方法
,让您能够访问使用google\u analytics\u api定义的数据
例如:
#app/controllers/analyics_controller.rb
Class AnalyticsController < ApplicationController
def index
@analytics = GoogleAnalytics.new
@new_users = @analytics.new_users
end
end
#lib/google_analytics.rb
Class GoogleAnalytics
def initialize
... google_analytics_api method here
end
def new_users
return [new_users_data]
end
end
#app/controllers/analyics_controller.rb
类AnalyticsController<应用程序控制器
def索引
@analytics=GoogleAnalytics.new
@新用户=@analytics.new\u用户
终止
终止
#lib/google_analytics.rb
类分析
def初始化
... google_analytics_api方法
终止
def新用户
返回[新用户\u数据]
终止
终止
需要注意的一点是,在没有模块的情况下,这是否会起作用。我想应该是的,但这对我来说还没有经过测试,从Skype上讲,我认为有几件事需要考虑
Init
目前,每当您想使用该模块时,您都在使用google\u analytics\u api
方法。这是完全没有效率的,这也是你现在有这个问题的部分原因。相反,我将创建一个init
方法,它将在每次您(并将GoogleAnalytics
放入它的一个类中)启动