How to split out a specific case from a polymorphic association

Augusts Bautra - Mar 28 - - Dev Community

Let's say we have a model structure that allows us to make comments on anything:

Comment.has_one :comment_commentee_tie

CommentCommenteeTie
  belongs_to :comment
  belongs_to :commentee, polymorphic: true

Post
  has_many :comment_commentee_ties
Enter fullscreen mode Exit fullscreen mode

Now let's say we want to filter comments by possible post data. To alleviate the joining, we can define a non-polymorphic association for Comment:

Comment
  has_one :comment_commentee_tie
  has_one :post, through: :comment_commentee_tie, source: :commentee, source_type: "Post"
Enter fullscreen mode Exit fullscreen mode

Polymorphic children

Let's look at the harder case with has_many :children, polymorphic: true

We can use the scope option to filter what types of children we want:

Parent
  has_many :parent_child_ties

  has_many(
    :good_children,
    -> { where(child_type: "GoodChild") },
    through: :parent_child_ties,
    source: :child,
    source_type: "GoodChild"
  )
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .