【问题标题】:acts-as-taggable-on tagged_with order('random()')在 tagged_with order('random()') 上充当可标记
【发布时间】:2012-09-03 18:16:12
【问题描述】:

我正在尝试将 act-as-taggable-on 的 tagged_with 方法与 random() 这样的订单一起使用,

Dvd.tagged_with(@site.tag, wild: true, any: true).order('RANDOM()').limit(20)

但我收到以下错误,

ActiveRecord::StatementInvalid: PG::Error: ERROR:  for SELECT DISTINCT, ORDER BY     expressions must appear in select list
LINE 1: ... OR dvds_taggings_c684506.tag_id = 3786) ORDER BY RANDOM() L...
                                                         ^
: SELECT  DISTINCT dvds.* FROM "dvds" JOIN taggings dvds_taggings_c684506  ON     dvds_taggings_c684506.taggable_id = "dvds".id AND dvds_taggings_c684506.taggable_type = 'Dvd' WHERE (dvds_taggings_c684506.tag_id = 72 OR dvds_taggings_c684506.tag_id = 2823 OR dvds_taggings_c684506.tag_id = 3786) ORDER BY RANDOM() LIMIT 20

知道如何解决这个问题吗?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 activerecord acts-as-taggable-on


    【解决方案1】:

    我不使用 Postgres - 但从搜索结果来看 - 看起来从 act_as_taggable-on 的 tagged_with 中被踢出的 DISTINCT 子句正在引发问题(至少根据 this pgsql thread 而言)

    从那篇文章开始,您可能可以使用 AREL 将其构造为子查询 - 类似于(我没有在任何地方的控制台中运行过它,但这可能会给您一个追求的方向)

    class Dvd < ActiveRecord::Base
    
      def self.random_list(limit = 20)
        with_scope do
          subquery = self.tagged_with(@site.tag, wild: true, any: true).pluck(:id)
          self.where("ID IN(#{subquery.to_sql})").order("RANDOM()").limit(limit)
        end
      end
    
    end
    

    这可能不是那么有效,但我的理解 ORDER BY RANDOM() 也不是(我曾经尝试从中获取随机集的所有数据都太小了,我可以加载所有数据,并使用 Array#shuffle 让 ruby​​ 给我一个随机列表 - 我怀疑你的 DVD 集小到足以做到这一点 - 除了相对独特的标签)。

    【讨论】:

    • 我并不感到惊讶 :-) - 这是我拥有的代码的复制和粘贴,并且有可能是疯狂的刺伤 - 对此感到抱歉。我必须提出一个示例项目来关注它( pluck(:id) 肯定会在 DVD 表和标签之间混淆,并且需要特定于表)。我还假设 act_as_taggable_on 返回一个范围,并且乍一看它看起来确实如此。如果我有时间,我会看看我能不能让它工作。要点是该论坛帖子表明需要子查询 - AREL 可以帮助使其易于构建。
    猜你喜欢
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    相关资源
    最近更新 更多