【问题标题】:How to get a single column's values into an array如何将单列的值放入数组
【发布时间】:2012-03-26 09:43:09
【问题描述】:

现在我正在做这样的事情来选择单列数据:

points = Post.find_by_sql("select point from posts")

然后将它们传递给一个方法,我希望我的方法保持不可知,现在必须从我的方法中调用 hash.point。如何快速将其转换为数组并将数据集传递给我的方法,还是有更好的方法?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3


    【解决方案1】:

    在 Rails 3.2 中有一个 pluck method 用于此

    就像这样:

    Person.pluck(:id) # SELECT people.id FROM people
    Person.pluck(:role).uniq # unique roles from array of people
    Person.distinct.pluck(:role) # SELECT DISTINCT role FROM people SQL
    Person.where(:confirmed => true).limit(5).pluck(:id)
    

    Difference between uniq and distinct

    【讨论】:

    • 数组如何通过 pluck 继承查询结果的排序?
    • Post.order(:score).pluck(:score) 是解决方案。谢谢。
    • 提取 id 有一个特殊的方法:Person.ids.
    • 还可以查看 Ernie Miller 的 gem Valium github.com/ernie/valium 特别是如果您使用的是旧版 Rails 或想要多列
    • 从 Rails 5.0 开始,现在推荐使用distinct 而不是uniq:所以Person.distinct.pluck(:role)
    【解决方案2】:

    您应该按照@alony 的建议使用pluck 方法。如果你在 Rails 3.2 之前被卡住了,你可以使用 ActiveRecord select 方法和 Array#map:

    Post.select(:point).map(&:point)
    #=> ["foo", "bar", "baz"] 
    

    在 Ruby 1.9 之前,您必须使用 .map{|x| x.title},因为在早期版本的 Ruby 中没有定义 Symbol#to_proc(由一元 & 运算符别名)。

    【讨论】:

    • 谢谢。我看到你评论了新的 Pluck 方法。你可以这样做吗?
    • 是的,如果您仔细阅读@alony 的回答,您会注意到她已经包含了一个这样做的示例。
    【解决方案3】:

    如果你看到 select_values 的定义,那么它使用 'map(&:field_name)'

      def select_values(arel, name = nil)
        result = select_rows(to_sql(arel), name)
        result.map { |v| v[0] }
      end
    

    Rails 收集数组中所有字段值的常用方法如下:

    points = Post.all(:select => 'point').map(&:point)
    

    【讨论】:

    • 好点。谢谢你。这很好用,并且让我仍然可以将订单和其他内容应用于查询,这与 Post.select 示例不同。
    • 我不同意你的观点,@franklinstine:Post.select(:point).limit(1) 执行 SELECT point FROM "posts" LIMIT 1Post.all(:select => :point).limit(1) 提出了NoMethodError。如果我错了,请纠正我。
    • 我同意你的 cmets。但是我没有在帖子中提到要使用的地方: Post.all(:select => :point).limit(1) 当然它会给出错误“未定义的方法`limit'”
    • @franklinstine 说他更喜欢你的方法,因为他可以在它之后链接其他语句,我只是想澄清这不是真的
    • 是的@padde 你误推了。我是说您仍然可以应用订单和其他查询语句,例如:Post.all(:select => 'score', :order => 'score ASC').map(&:score)。
    【解决方案4】:
    points = Post.all.collect {|p| p.point}
    

    【讨论】:

    • 这可行,但是您从数据库中选择所有字段,然后在 Ruby 中过滤结果,而 select 语句仅获取指定的列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 2022-08-18
    • 2020-06-27
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多