根据rails中的不同键合并2个哈希数组

时间:2017-02-22 16:15:45

标签: ruby-on-rails arrays ruby hash

我有2个查询结果,其中一个是像这样的哈希数组

[{"user_id"=>"1", "latlng"=>[#<BigDecimal:7fc67f8412d0,'0.43653226E2',18(36)>, #<BigDecimal:7fc67f840560,'-0.793831843E2',18(36)>], "loc"=>["Toronto", "Ontario", "Canada"]}, {"user_id"=>"2", "latlng"=>[#<BigDecimal:7fc67f84a8f8,'0.43653226E2',18(36)>, #<BigDecimal:7fc67f849d18,'-0.793831843E2',18(36)>], "loc"=>["Toronto", "Ontario", "Canada"]}, {"user_id"=>"3", "latlng"=>[#<BigDecimal:7fc67f848828,'0.43653226E2',18(36)>, #<BigDecimal:7fc67f848210,'-0.793831843E2',18(36)>], "loc"=>["Toronto", "Ontario", "Canada"]}, {"user_id"=>"4", "latlng"=>[#<BigDecimal:7fc67f852620,'0.43653226E2',18(36)>, #<BigDecimal:7fc67f851b30,'-0.793831843E2',18(36)>], "loc"=>["Toronto", "Ontario", "Canada"]}, {"user_id"=>"5", "latlng"=>[#<BigDecimal:7fc67f85ae88,'0.43653226E2',18(36)>, #<BigDecimal:7fc67f85a9b0,'-0.793831843E2',18(36)>], "loc"=>["Toronto", "Ontario", "Canada"]}]

第二个是用户的活动记录关系对象,

<ActiveRecord::Relation [#<User id: 4, email: "hello.misc@gmail.com", username: "steve", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 13, current_sign_in_at: "2017-02-18 21:16:17", last_sign_in_at: "2017-01-14 20:32:57", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", confirmed_at: "2016-12-13 01:42:57", confirmation_sent_at: "2016-12-13 01:42:55", unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2016-12-13 01:42:55", updated_at: "2017-02-18 22:03:46", slug: "user2", uuid: "xdn5n5z3fmr4", impressions_count: 1, likers_count: 3, lat: #<BigDecimal:7fc67fc39130,'0.0',9(27)>, lng: #<BigDecimal:7fc67fc38c30,'0.0',9(27)>, currently_online: false, status: "unverified", deleted_at: nil>, #<User id: 5, email: "jack@gmail.com", username: "user21", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2017-02-17 02:49:07", last_sign_in_at: "2017-02-17 02:49:07", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", confirmed_at: "2017-02-17 02:49:10", confirmation_sent_at: "2017-02-17 02:49:07", unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2017-02-17 02:49:07", updated_at: "2017-02-17 02:49:43", slug: "user21", uuid: "xtffdh2ajnp7", impressions_count: 1, likers_count: 0, lat: #<BigDecimal:7fc67fca6758,'0.0',9(27)>, lng: #<BigDecimal:7fc67fca5ec0,'0.0',9(27)>, currently_online: false, status: "unverified", deleted_at: nil>]>

我想要做的是根据第一个数组的外键将第一个哈希数组合并到activerecord关系中,

因此,如果第一个数组的user_id为3,我想将该哈希值插入活动记录对象上ID为3的用户的活动记录中。

我想出了这个

index = a1.group_by{|entry| entry["id"]} i2= a2.map{|entry| (index[entry.id] || []).reduce(entry, :merge) }

但它根本没有将它们合并在一起..我做错了什么?

编辑:并非所有第一个数组都是相关的,我只想根据第二个查询的活动记录集合中返回的内容有选择地从第一个数组中获取项目

edit2:我不打算将数据保存回来,我只是想合并数据集以在视图模板中显示它。

2 个答案:

答案 0 :(得分:1)

如果您对集合使用@Override protected void onPostExecute(typeYouDefinedAsArgument myArgument){ super.onPostExecute(myArgument); if(id == 0) { System.out.println("postexecuting!"); edPas.setError("Nickname and password don't match!"); loadBar.setVisibility(View.GONE); } else { System.out.println("Less postexecuting!"); onBackPressed(); } Array#map,那么您最终会得到一个数组而不是ActiveRecord集合,这可能不是您想要的。

您可以向User模型添加虚拟属性,然后遍历集合:

collect

这可能不会非常有效,但对于一个小的分页数据集,这可能不是什么大问题。

另一种选择是使用decorator pattern,它就像是围绕用户对象的包装器。在这种情况下,您可以将您的位置属性添加到装饰器,而不是将它们注入到集合中。查看Draper gem以获得良好的概述。

答案 1 :(得分:0)

如果我理解正确,你可以这样做:

# users is an array of ActiveRecord::Relation
# extra_data is the hash
users.each do |user|
  # .detect basically will return an object (first appearance) or nil
  data = extra_data.detect{|d| d["user_id"].to_i == user.id}
  if data.present?
    user.lat = data["latlng"][0]
    user.lng = data["latlng"][1]
    # if you want to attach "loc", add a attr_accesor :loc in your Use model
    # user.loc = data["loc"]
  end
end

如果您想了解有关detect方法的更多信息,请read the docs