1

I have 3 models named User, Photo and Report

Model Report is a polymorphic class and is used to report users and photos and model User has a polymorphic association with the Modal Photo.

So the functionality is a user can report photos or any other users.

below is the migration file of Report.

class CreateReports < ActiveRecord::Migration
  def change
    create_table :reports do |t|
      t.integer :user_id
      t.integer :reported_id
      t.string :reported_type, default: "User"
      t.string :note, default: ""
    end
 end
end

and below are the associations

class User < ActiveRecord::Base
  ...
  has_many :photos, as: :attachment
  has_many :reports, dependent: :destroy
  ...
end

class Photo < ActiveRecord::Base
  ...
  belongs_to :attachment, :polymorphic: true
end

class Report < ActiveRecord::Base
  belongs_to :user
  belongs_to :reported, polymorphic: true
end

currently i use a query like below to get reported list of a user either by the user itself or by their photos.

 Report.where("(reported_id=? AND reported_type=?) OR (reported_id in (?) AND reported_type=?)", 
  self.id, "User", self.photos.pluck(:id), "Photo")

So, i would like to know how can i achieve same thing with an has_many association ?

Please help me if there is any better way which i can achieve the same or correct me if i'm wrong.

Vishal Taj PM
  • 1,339
  • 11
  • 23

1 Answers1

1

Rails are smart enough to use argument's class in filtration by a polymorphic association. You may rewrite your condition in a very simple way:

Report.where(reported: [self] + self.photos)

# result sql
SELECT  "reports".* 
FROM "reports" 
WHERE (
  ("reports"."reported_type" = 'User' AND "reports"."reported_id" = 1) OR 
  ("reports"."reported_type" = 'Photo' AND "reports"."reported_id" IN (1, 2))
) 

This code works only in Rails 5.x.

Update

In Rails 4.2 this code will not work. You may check related SO questions: Finding record where polymorphic association or nil and OR operator in WHERE clause with Arel in Rails 4.2

I think, your current code is the best you can do in Rails 4.2

Community
  • 1
  • 1
Ilya Lavrov
  • 2,810
  • 3
  • 20
  • 37