【问题标题】:Return first record per group返回每组的第一条记录
【发布时间】:2015-07-07 17:05:01
【问题描述】:

如何获取包含记录的 ActiveRecord::Relation 对象,其中每个记录是每个 book第一个 author

# Models
class Author < ActiveRecord::Base
  has_many :authors_books
end

class AuthorsBook < ActiveRecord::Base
  belongs_to :author
  belongs_to :book
end

class Books < ActiveRecord::Base
  has_many :authors_books
end

@author_books = AuthorsBooks.all

@author_books.all 返回的示例行/记录

author_id    book_id
   3           1
   2           1
   3           1
   4           1
   1           2
   1           3
   2           4
   3           4

现在我只想获取 first author per book

应该返回这个:

author_id    book_id
   3           1
   1           2
   1           3
   2           4

【问题讨论】:

  • @author_books 是根据 AuthorBooks 表的 id 排序的结果。你想要每本书的第一作者然后创建吗?我的意思是基于 AuthorBooks 记录的 created_at 时间。
  • 定义第一作者?
  • 可能这就是你想要的...AuthorsBooks.all.group_by(&amp;:book_id).collect{|k,v| v.first}
  • 这对你有用吗?
  • 很高兴我能帮上忙...

标签: mysql ruby-on-rails ruby activerecord rails-activerecord


【解决方案1】:
# returns an array of active record objects
ary_authorbook_objs = AuthorsBook.all.group_by(&:book_id).collect{|k,v| v.first}

# transforms that array of active record objects into one ActiveRecord::Relation object
active_relation_object = AuthorsBook.where(id: ary_authorbook_objs.map(&:id))

【讨论】:

    【解决方案2】:

    你可以试试inject:

    AuthorsBook.all
               .inject({}){|h, k| h[k.book_id] = k unless h.key? k.book_id; h}
               .values
    

    【讨论】:

    • 是否可以返回活动记录对象?我注意到您的方法返回的哈希值仅包含每组第一个 authorauthor_id。如果可能的话,我希望每个返回的记录都有实际的对象,而不是键/值对。
    • 很遗憾,您的解决方案似乎不适用于我们的目的。您的解决方案不是获取每组的第一条记录。相反,您的解决方案是获取每个组的最小 author_id。我们正在尝试获取每个组的实际第一条记录(无论第一条记录是否恰好具有最小 author_id 都无关紧要)。希望这是有道理的。
    • 我们将其应用于现实世界的问题:它首先被适当地排序。因此,既然我们知道它是按我们想要的方式排序的,我们希望每组抓取第一个。
    猜你喜欢
    • 1970-01-01
    • 2018-09-13
    • 2023-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多