如何将ActiveRecord关系数组转换为一个键入其中一个参数的哈希?

时间:2015-11-03 02:12:06

标签: ruby-on-rails ruby activerecord hash

我正在创建一个原始的SQL upsert,我有一个相当大的ActiveRecord关系数组,我需要转换为一个哈希。我需要键入哈希来选择我正在选择的其中一个参数,这样我就可以快速得到该值。

I found this response using as_json我几乎可以得到我需要的东西,但它并不完全存在。

profiles = Profile.all.select(:id, :foo)  #returns an array of ActiveRecord Relations
profiles = profiles.as_json

产量

{:id => 123, :foo => "bar"}
{:id => 456, :foo => "baz"}

但我想要的是

{123 => "bar", 456 => "baz"}

我意识到我可以将as_json的结果映射到一个新的哈希,但我必须在几百万条记录上相当频繁地运行它。这也是一个较大的rake任务的一小部分,我希望将所有记录循环到最小。

我手动执行此操作而不是让ActiveRecord处理它的原因是它最初需要24小时才能运行任务,即使使用activerecord-import也只能加速约12小时。 I chose to go with using raw sql based off the benchmarks made in this blogpost

4 个答案:

答案 0 :(得分:3)

在Rails4中,你可以做到

A,B
1.000000000000000000e+00,2.000000000000000000e+00
3.000000000000000000e+00,4.000000000000000000e+00
5.000000000000000000e+00,6.000000000000000000e+00

答案 1 :(得分:1)

你可以使用Profile.connection.select_all("select id, foo from profiles;") => [{"id" => xxx, "foo" => xxx}, {}, .....] 方法获取一个哈希数组而不是ActiveRecord对象,它更快,内存消耗更少。

public void queryBundleWithName(){

    var query = ParseObject.GetQuery ("AssetBundle").
        WhereEqualTo("name", "Board");

    query.FirstAsync().ContinueWith(t =>{
        ParseObject relatedObjects = t.Result;
        string name = relatedObjects.Get<string>("name");
        //isFinish = true;

        urlVideo = relatedObjects.Get<ParseFile>("video").Url.AbsoluteUri;
        textResult.text =  urlVideo;

        Screen.orientation = ScreenOrientation.LandscapeLeft;
        Handheld.PlayFullScreenMovie (urlVideo, Color.black, FullScreenMovieControlMode.CancelOnInput, FullScreenMovieScalingMode.AspectFill);
    });
}

然后将结果转换为您想要的格式。

答案 2 :(得分:0)

profile模型上,您可以执行此操作以获得所需结果:

  def self.to_hash
    Hash[*all.map{|p| [p.id, p.foo]}.flatten]
  end

然后,您可以致电:Profile.select(:id, :foo).to_hash

答案 3 :(得分:0)

我可能会绕过ActiveRecord并将数据从数据库中直接插入Hash,如下所示:

Profile.connection
       .execute('select id, foo from profiles')
       .each_with_object({}) { |row, h| h[row['id'].to_i] = row['foo'] }

或者更好(IMO),也可以绕过Rails和Ruby,并使用SQL,临时表等在数据库中执行所有操作。当您处理大量数据时,最好的选择通常是完全忽略你的应用程序并在数据库中做所有事情;数据库非常适合处理大量数据,这是他们所做的事情。