Reputation: 11336
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
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