0

我正在尝试将两个过滤器应用于 Rails 3 中的数据库查询。第一个过滤器仅显示图像类型的媒体。第二个过滤器显示了最受好评的故事。过滤器本身可以正常工作,但是当我尝试组合两个过滤器时,出现错误。

涉及3张桌子。故事、回忆和致敬。敬礼表记录某人“敬礼”记忆的次数。每个故事都由多个记忆组成。一个故事的总敬礼是那个故事的记忆敬礼的总和。我想按敬礼从高到低的顺序检索仅图像故事的记录。

模型/story.rb

def self.where_contains_image()
  joins(
    'INNER JOIN memories AS wci_memories ON wci_memories.story_id = stories.id'
  )
  .where(
    'wci_memories.media_type_cd = ?', Memory.image
  ).uniq
end

控制器/story_controller.rb

if params[:filter_content] == 'image'
  stories = stories.where_contains_image
end

if (params[:filter_trends] == 'most_saluted')
  stories = stories.order("(SELECT COUNT(1) FROM salutes
    LEFT JOIN memories AS ms_memories ON salutes.content_id = ms_memories.id
    LEFT JOIN stories AS ms_stories ON ms_stories.id = ms_memories.story_id
    WHERE ms_stories.id = stories.id AND salutes.content_type = 'Memory')
    DESC");
end

就其本身而言,当设置了 'most_saluted' 参数时,查询会按预期工作。当设置了“most_saluted”参数和“image”参数时,我得到一个错误:

for SELECT DISTINCT, ORDER BY expressions must appear in select list

我明白错误是什么,但我不知道如何重写查询,以便它只能返回按最敬礼的顺序排列的图像。

当我在数据库上运行这个 SQL 查询时,它会返回我正在寻找的记录。但我无法弄清楚如何让 rails 返回相同的记录。此外,此查询结合了两个过滤器(仅图像和最高敬礼)。我想将它们分开,以便我可以单独应用一个过滤器,或同时应用两者。

SELECT DISTINCT stories.*, (SELECT COUNT(1) FROM salutes
    LEFT JOIN memories AS ms_memories ON salutes.content_id = ms_memories.id
    LEFT JOIN stories AS ms_stories ON ms_stories.id = ms_memories.story_id
    WHERE ms_stories.id = stories.id AND salutes.content_type = 'Memory') 
AS total_salutes FROM stories INNER JOIN memories AS wci_memories 
ON wci_memories.story_id = stories.id WHERE wci_memories.media_type_cd = 0
ORDER BY total_salutes DESC

关于如何解决这个问题的任何想法?

4

1 回答 1

0

您可以使用范围来实现这一点,实际上 Activerecord 范围是链接条件的更清洁/模块化的方式

在此处阅读有关范围的信息

高温高压

于 2013-01-03T22:00:30.163 回答