如何使用Active Record计算组中的记录数?

时间:2014-06-30 13:24:56

标签: ruby-on-rails ruby activerecord

我有一个文件列表和这些文件中的单词列表。 foreign_key是字段filenum。 一个文件可以有一个单词的多个出现,因此wordtable可以为一个单词具有不同单词位置的文件表的条目数。

我的Active Record课程是:

class File1 < ActiveRecord::Base
  self.table_name = :filetable
  self.primary_key = :FileNum
  belongs_to :word
end

class Word < ActiveRecord::Base
  self.table_name = :wordtable
  self.primary_key = :fileNum
  has_one :file1, foreign_key: :filenum, primary_key: :filenum
end

我的查询是:

query = 'ole'
Word.where(['name LIKE ?', "%#{query}%"]).group(:fileNum).each do |word, occurences|
  printf "%-24s %12s %12s\n" %  [word.name, word.file1.FilePath, occurences]
end

这是我当前结果的一个子集:

ole       C:\Users\user\ruby\_nakijken\stringbuilder_list_properties.rb             
boolean   C:\Users\user\ruby\_nakijken\s_pinger.rb             
console   C:\Users\user\ruby\_nakijken\s_transition.rb
ole       C:\Users\user\ruby\_nakijken\save_outlook_message.rb   
...

除了出现的总数之外,查询有效。我想在该文件中出现该单词的出现次数。 我该怎么做?

目前,id这样做有点丑陋

query = 'require'
name, filenum, count, filepath = '', 0, 0, ''

Word.where(['name LIKE ?', "%#{query}%"]).group(:name, :filenum, :position).each do |word|
  if filenum == 0
    name, filenum, count, filepath = word.name, word.filenum, 1, word.file1.FilePath
  elsif name == word.name && filenum == word.filenum
    count += 1
  else
    printf "%-24s %12s (%s)\n" %  [name, filepath, count]
    name, filenum, count, filepath = word.name, word.filenum, 1, word.file1.FilePath
  end
end
if filenum == 0
  puts "'#{query}' not found"
else
  printf "%-24s %12s (%s)\n" %  [name, filepath, count]
end

1 个答案:

答案 0 :(得分:1)

查看documentation

  

如果countgroup一起使用,则会返回其键Hash   表示聚合列,值是相应的   量:

Person.group(:city).count
# => { 'Rome' => 5, 'Paris' => 3 }

您似乎应该在查询中添加count

query = 'ole'
Word.where(['name LIKE ?', "%#{query}%"]).group(:fileNum).count.each do |fileNum, occurences|
  # ...
end

对于您当前的解决方案(因为我的解决方案似乎不起作用),我可以使用group_by建议更清洁的版本:

grouped_words = Word.where(['name LIKE ?', "%#{query}%"]).group(:name, :filenum, :position)
grouped_words.group_by { |group| [group.name, group.filenum] }.each do |(name, _), words|
  printf "%-24s %12s (%s)\n" %  [name, words.first.file1.FilePath, words.count]
end