【问题标题】:How would I sort all the values of an array of hashes in Rails? Mongo如何对 Rails 中哈希数组的所有值进行排序?蒙哥
【发布时间】:2014-03-07 08:13:30
【问题描述】:

我有一个控制器动作可以为我获取一些信息:

@account = Account.find(params[:id])
@acct_cust = Customer.all(:account_id => @account.id.to_s)
@acct_cust.each do |ac|
  @jobAc << Job.where(:customer_id => ac.id).sort(:start_date)
end

我们有账号,然后我们抓取属于这个账号的所有客户,然后我们抓取每个客户的所有工作,然后把他们塞进一个数组中。

所以我要做的是按 :start_date 值对最终数组 - @jobAc 进行排序。

当然,正如您在日志中看到的那样,我首先将勇敢的查询推送到这个数组中:

控制台日志:

 jobAc is [#<MongoMapper::Plugins::Querying::DecoratedPluckyQuery customer_id:  
 BSON::ObjectId('52705ff24031a0000e000179'), sort: [["start_date", 1]], transformer:  
 #<Proc:0x007fe3e6f834d8@/usr/local/rvm/gems/ruby-2.0.0-p247/gems/mongo_mapper-0.13.0.beta2
 /lib/mongo_mapper/plugins/querying.rb:66 (lambda)>>, 
 #<MongoMapper::Plugins::Querying::DecoratedPluckyQuery customer_id: 
 BSON::ObjectId('5279795e2f6984000b00014f'), sort: [["start_date", 1]], transformer: 
 #<Proc:0x007fe3eb13b8f8@/usr/local/rvm/gems/ruby-2.0.0-p247/gems/mongo_mapper-0.13.0.beta2
 /lib/mongo_mapper/plugins/querying.rb:66 (lambda)>>, 
 #<MongoMapper::Plugins::Querying::DecoratedPluckyQuery customer_id: 
 BSON::ObjectId('52797beb2f698400ef0000c4'), sort: [["start_date", 1]], transformer: 
 #<Proc:0x007fe3e9da35e8@/usr/local/rvm/gems/ruby-2.0.0-p247/gems/mongo_mapper-0.13.0.beta2
 /lib/mongo_mapper/plugins/querying.rb:66 (lambda)>>, 
 #<MongoMapper::Plugins::Querying::DecoratedPluckyQuery customer_id: 
 BSON::ObjectId('527dac2d3d126f0107000059'), sort: [["start_date", 1]], transformer: 
 #<Proc:0x007fe3eb170cb0@/usr/local/rvm/gems/ruby-2.0.0-p247/gems/mongo_mapper-0.13.0.beta2
 /lib/mongo_mapper/plugins/querying.rb:66 (lambda)>>]

如果我使用@jobAc = Job.all(query),我最终会得到一个这样的值数组:

[[{1},{2},{3}],[{1},{2}]]

我什至无法理解我要正确提出的问题 :) 我是在尝试展平哈希数组吗?我试过了,但没有想出我的想法。

我试过了:

@jobAc.sort_by!(&amp;:start_date).reverse but this of course cannot be done while they are plucky queries instead of the actual values.

有什么想法吗?

【问题讨论】:

    标签: arrays ruby-on-rails-3 mongodb hash


    【解决方案1】:

    这里的问题是您在循环中一次只选择部分数据集,而不是对整个数据集进行排序。

    您可以改进此代码的运行时间并应用排序,方法是执行单个查询以查找所有作业,使用排序参数:

    @account = Account.find(params[:id])
    @acct_cust = Customer.all(:account_id => @account.id.to_s)
    @jobAc = Job.where(:customer_id.in => @acct_cust.map(:id)).sort(:start_date)
    

    由于您使用的是 MongoMapper,我建议您使用关联和范围:

    class Account
      many :customers
    end
    
    class Customer
      belongs_to :account
    end
    
    class Job
      scope :for_account, ->(account) do
        where(:customer_id.in => account.customers.fields(:id).all.map(:id))
      end
    end
    

    然后您可以找到给定客户的所有工作:

    @jobAc = Job.for_account( Account.find(params[:id]) )
    

    【讨论】:

    • 嗨,克里斯——我知道你是谁——感谢你的辛勤工作!并感谢您回答这个问题。您编写的查询在顶部有效(此时超出我的理解范围),但您在下面编写的范围会引发错误。语法需要更改为 .map(&:id) 但即便如此我在页面加载时得到“错误数量的参数(1 代表 0)”。我正在使用 mongo_mapper 0.13.0.beta2 gem - 也许这是一个错误。谢谢你的帮助
    • 抱歉,map(:id) 仅适用于 Ruby 2.0。异常的堆栈跟踪是什么样的?
    • 唯一可行的方法是使用这样的 & 语法:scope :for_account, ->(account) do where(:customer_id.in => account.customers.fields(:id)。 all.map(&:id)).sort(:start_date.desc) end 但是现在效果很好!
    猜你喜欢
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 2020-04-05
    • 2019-04-25
    • 2015-04-08
    • 2018-05-18
    • 1970-01-01
    相关资源
    最近更新 更多