![](/img/trans.png)
[英]Ruby Rails preserve a variable used in one method for another method to access
[英]Access Local variable in another method Ruby
我想了解如何访问方法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_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 。
那么,如果我想要另外2个单独的方法将返回不同的结果集,那么新用户和跳出率又将是两个单独的调用来更改请求参数,该怎么办呢? 我需要重复整个方法吗?
有没有一种方法可以重构它,以便可以将授权调用包装在其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
问题之一是在new_users方法中可以使用局部变量client和result ,这些可以更改为什么? 一个带有@的实例变量? 或带有@@的类变量?
您的直觉是很好的-您不想重复自己 ,并且有更好的方法来构造此代码。 但是,与其共享变量 ,不如考虑一些松散连接的小块 。 编写将一件事情做好的方法,并将其组合在一起。 例如,我们可以编写一个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
它之所以protected
是因为外部代码(您的Analytic
类之外的东西)不应直接与其一起使用。 他们应该使用我们为他们提供的方法。
您还可以提供一个帮助程序方法,以从API获取结果。 我对查询API不熟悉,但看起来是您的metrics
值发生了变化。 所以也许是这样的:
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_visits
将返回get_result('ga:pageViews')['totalsForAllResults']['ga:pageviews']
。 您课外的代码不必了解GA数据格式即可使用。 这称为封装 。
通过谈论Skype,我认为有几件事要看
在里面
当前,每次要使用该模块时,您都在使用google_analytics_api
方法。 这是完全低效的,部分原因就是您现在遇到此问题。 相反,我将创建一个init
方法,该方法将在每次初始化对象时触发(并使GoogleAnalytics
成为其自己的类):
#lib/google_analytics.rb
Class GoogleAnalytics
def initialize
... google_analytics_api method here
end
end
这将允许您将当前模块视为真正的Ruby对象-如下所示:
@analytics = GoogleAnalytics.new #-> fires initialize method
这将使您能够调用对象(这将从API中提取数据),然后针对您所拥有的不同用例相应地拆分数据。
实例方法
这使我很好地了解了实例方法的思想
您所指的,乃至Alex P
所指的,实际上是实例方法的概念。 这可以兼作对象的属性 ,但从本质上讲,您可以在方法的实例上调用功能。
因此,在Alex的示例中,您有:
def new_users
get_result('ga:newUsers')
end
这只是调用您的类的instance
方法:
GoogleAnalytics::Analytic.new_users
这将创建Analytic
类的实例,然后调用new_users
方法(应为class method
)。 然后,该方法将允许您在新初始化的对象上调用instance
方法,因此get_result
方法将被调用
-
我的建议是在对象初始化后使用instance methods
,使您能够访问使用google_analytics_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
需要注意的一个问题是,如果没有该模块,这是否可以工作。 我认为应该,但是未经我测试
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.