Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order by polymorphic belongs_to attribute

How do I make an ActiveRecord query that orders by an attribute of a polymorphic belongs_to association?

For example I have model called Tagging that has a polymorphic belongs_to association named tagged_item.

Unfortunately Tagging.joins(:tagged_item) throws a ActiveRecord::EagerLoadPolymorphicError. So I can't do something like Tagging.joins(:tagged_item).order("tagged_item.created_at DESC").

Any suggestions?

like image 855
Zardoz Avatar asked Nov 05 '22 19:11

Zardoz


1 Answers

You can't make a join directly with a polymorphic relationship because the polymorphic objects' data are in different tables. Still you could try to do it manually as in the following example.

class Tagging < ActiveRecord::Base
  belongs_to :tagged_item, :polymorphic => true
end

class Post
  has_many :image_tagging, :as => :tagged_item
end

class Comment
  has_Many :image_tagging, :as => :tagged_item

Tagging.select("taggins.*, COALESCE(posts.created_at, comments.created_at) AS tagged_item_created_at").
  joins("LEFT OUTER JOIN posts ON posts.id = tagging.tagged_item_id AND tagging.tagged_item_type = 'Post'").
  joins("LEFT OUTER JOIN comments ON comments.id = tagging.tagged_item_id AND tagging.tagged_item_type = 'Comment'").
  order("tagged_item_created_at DESC")

COALESCE chooses the first column provided if exists otherwise the other one. It's the same as IFNULL in mysql or you could even use CASE WHEN ... IS NULL THEN ... ELSE ... END

like image 194
polmiro Avatar answered Nov 09 '22 13:11

polmiro