Martin
Martin

Reputation: 11336

acts-as-taggable-on tagged_with order('random()')

I'm trying to use act-as-taggable-on's tagged_with method with a random() order like this,

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

But I'm getting the following error,

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

Any idea how to solve this?

Upvotes: 1

Views: 477

Answers (1)

jay
jay

Reputation: 313

I don't use Postgres - but from a search - it looks like the DISTINCT clause that is getting kicked out from act_as_taggable-on's tagged_with is throwing a kink into things (at least according to this pgsql thread

Following along from that post, you could probably construct this as a subquery using AREL - something like (I haven't ran this in a console anywhere, but this may give you a direction to pursue)

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

It's probably not all that efficient, but my understanding that ORDER BY RANDOM() isn't either (all the data that I've ever tried to get a random set from was so small I could just load all of it, and use Array#shuffle to let ruby give me a random list - I doubt your Dvd set is small enough to do that - except for relatively unique tags).

Upvotes: 1

Related Questions