Ruby on rails Rails自定义分组依据

Ruby on rails Rails自定义分组依据,ruby-on-rails,ruby,activerecord,group-by,Ruby On Rails,Ruby,Activerecord,Group By,我有一个存储天数的数组分区 我想根据我的帖子ActiveRecord::Relation将_分组,根据它们的年龄和所在分区 示例:分区=[0,40,60,90] 我想把0到40天,40到60天,60到90天和90天以上的帖子分组 请注意,我将从外部源获取数组数据,我不想使用where子句,因为我使用的是includes和where db查询使includes无效 我如何才能做到这一点?根据文章中的描述,以下操作可以帮助您对数据进行分组: result_array_0_40 = [];result

我有一个存储天数的数组分区

我想根据我的帖子ActiveRecord::Relation将_分组,根据它们的年龄和所在分区

示例:分区=[0,40,60,90]

我想把0到40天,40到60天,60到90天和90天以上的帖子分组

请注意,我将从外部源获取数组数据,我不想使用where子句,因为我使用的是includes和where db查询使includes无效


我如何才能做到这一点?

根据文章中的描述,以下操作可以帮助您对数据进行分组:

result_array_0_40 = [];result_array_40_60 = [];result_array_60_90 = [];result_array_90 = [];
result_json = {}
现在,我们需要迭代值并手动将它们分组到动态键值对中

PARTITION.each do |x|
    result_array_0_40.push(x) if (0..40).include?(x)
    result_array_40_60.push(x) if (40..60).include?(x)
    result_array_60_90.push(x) if (60..90).include?(x)
    result_array_90.push(x) if x > 90
    result_json["0..40"]  = result_array_0_40
    result_json["40..60"] = result_array_40_60
    result_json["60..90"] = result_array_60_90
    result_json["90+"]    = result_array_90
end
希望能有帮助

假设: 此分区用于显示目的。 要按天分组的属性为天 你想把结果变成散列 {0=>[],40=>[],60=>[],90=>[]

将这些方法添加到模型中

# post.rb

def self.age_partitioned
  group_by(&:age_partition)
end

def age_partition
  [90, 60, 40, 0].find(days) # replace days by the correct attribute name
end

# Now to use it

Post.where(filters).includes(:all_what_you_want).age_partitioned

这里有一个简单的方法:

posts.each_with_object(Hash.new { |h, k| h[k] = [] }) do |post, hash|
  days_old = (Date.today - post.created_at.to_date).to_i
  case days_old
  when 0..39
    hash[0] << post
  when 40..59
    hash[40] << post
  when 60..89
    hash[60] << post
  when 90..Float::INFINITY # or 90.. in the newest Ruby versions
    hash[90] << post
  end
end
希望这有帮助-如果你有任何问题,请告诉我

编辑:如果您的分区来自外部源,则会有一点麻烦,尽管以下方法可行:

# transform the PARTITIONS into an array of ranges
ranges = PARTITIONS.map.with_index do |p, i|
  return 0..(p - 1) if i == 0 # first range is 0..partition minus 1
  return i..Float::INFINITY if i + 1 == PARTITIONS.length # last range is partition to infinity
  p..(PARTITIONS[i + 1] - 1)
end

# loop through the posts with a hash with arrays as the default value
posts.each_with_object(Hash.new { |h, k| h[k] = [] }) do |post, hash|
  # loop through the new ranges
  ranges.each do |range|
    days_old = Date.today - post.created_at.to_date
    hash[range] << post if range.include?(days_old) # add the post to the hash key for the range if it's present within the range
  end
end

可能的重复可以用同样的方法解决,但我不认为它是重复的@Sixty4Bit你能提一下你想要的样本输出吗?这对@UmeshMalhotra有帮助吗?
# transform the PARTITIONS into an array of ranges
ranges = PARTITIONS.map.with_index do |p, i|
  return 0..(p - 1) if i == 0 # first range is 0..partition minus 1
  return i..Float::INFINITY if i + 1 == PARTITIONS.length # last range is partition to infinity
  p..(PARTITIONS[i + 1] - 1)
end

# loop through the posts with a hash with arrays as the default value
posts.each_with_object(Hash.new { |h, k| h[k] = [] }) do |post, hash|
  # loop through the new ranges
  ranges.each do |range|
    days_old = Date.today - post.created_at.to_date
    hash[range] << post if range.include?(days_old) # add the post to the hash key for the range if it's present within the range
  end
end
posts.group_by |post|
  days_old = (Date.today - post.created_at.to_date).to_i
  case days_old
  when 0..39
    0
  when 40..59
    40
  when 60..89
    60
  when 90..Float::INFINITY # or 90.. in the newest Ruby versions
    90
  end
end