假设我有Campaign#show action,如下所示:
def show
@campaign = Campaign.find(params[:id])
end
假设,我希望在我的视图中显示我从YouTube API获得的一些信息,用变量编写,因此Campaign#show现在看起来像这样:
def show
@campaign = Campaign.find(params[:id])
@views = Campaign.youtube_info(@campaign.url) # this class method of Campaign
end
但为了方便起见,我想合并@campaign和@views,并在@campaign中使用@campaign [:views] [:view_count]。
据我所知@campaing是ActiveRecord对象,而@views是Hash,不允许进行此类合并。
在这种情况下,最好的方法是什么?
提前致谢。
答案 0 :(得分:2)
首先,您将向视图传递任意数量的对象,作为普通Rails应用程序的一部分。使用@views
和@campaign
完全没有错。
然而,在你的情况下,事情写得非常奇怪。
首先,views
应该是Campaign
上的方法,它应该只调用youtube_info
。
奇怪的是youtube_info
是类级方法,因为它需要从类的实例输入属性。它应该是一个实例方法,您只需在视图中调用该方法即可。
如果要阻止对每次调用的API进行额外调用,请缓存第一次调用的结果。 “缓存”方法的返回值的过程称为 memoization ,您可以在Ruby世界中找到很多关于它的文章。以下是Ruby中的极常见模式:
class Campaign < ActiveRecord::Base
def youtube_info
@youtube_info ||= perform_some_api_request(@url)
end
def views
youtube_info['views']
end
end
方法youtube_info
仅在首次运行时调用perform_some_api_request
方法。结果将分配给@youtube_info
,然后返回。每个后续调用都将测试@youtube_info
,如果将其设置为非虚假值,则返回它。每次调用views
都只会调用youtube_info
,只有第一次调用才会执行API调用。
你可以使用相同的技术,并保持你的代码完全按照书面形式,改为调用类级方法,但我不推荐它:
class Campaign < ActiveRecord::Base
def self.youtube_info(url)
# ...
end
def views
@views ||= Campaign.youtube_info(@url)['views']
end
end
但是,第一个例子更好。 youtube_info
没有理由成为类级方法。