Memoize 多行方法 - Rails

Bit*_*ise 0 ruby ruby-on-rails memoization

在使用 Rails 之前,我从未实现过备忘,我想我遇到了一个很好的用例,但我不知道该怎么做。这是我正在使用的内容:

方法:

 def manager_rep_code_and_name
    manager = []

    rep_code_list.each do |rep_code|
      context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)

      manager.push({name: context.manager.response.first["Name"], rep_code: rep_code})
    end

    manager
  end
Run Code Online (Sandbox Code Playgroud)

此方法进行网络调用,可能需要一段时间才能弄清楚所有这些。有没有办法可以使用memoize这种方法,所以如果它已经存在,我就不必再出去提出这个请求了。

像这样的东西:

def manager_rep_code_and_name
   @managers ||= manager = []

   rep_code_list.each do |rep_code|
     context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)

     manager.push({name: context.manager.response.first["Name"], rep_code: rep_code})
   end

  manager
end
Run Code Online (Sandbox Code Playgroud)

显然,这行不通,但我现在有点卡住了。

fko*_*ler 9

您可以使用begin end块来记住多行代码的结果:

def manager_rep_code_and_name
   @manager_rep_code_and_name ||= begin
     manager = []

     rep_code_list.each do |rep_code|
       context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)

       manager.push({name: context.manager.response.first["Name"], rep_code: rep_code})
     end

    manager
  end
end
Run Code Online (Sandbox Code Playgroud)


Ste*_*fan 6

我经常把这样的方法分开:

def fetch_manager_rep_code_and_name
  rep_code_list.map do |rep_code|
    context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)
    { name: context.manager.response.first['Name'], rep_code: rep_code }
  end
end

def manager_rep_code_and_name
  @manager_rep_code_and_name ||= fetch_manager_rep_code_and_name
end
Run Code Online (Sandbox Code Playgroud)

通常,这也使它们更易于测试。