Search code examples
ruby-on-railsactiverecordarel

Rails ActiveRecord query combined with a method filter - how to rewrite this?


I have the following code, which results in one query for the PodAdmins and then x following queries, one for every Pod in the database!

pod_admins = PodAdmin.where("pod_id IS NOT null")

pod_admins.select{|pa| pa if pa.pod.is_active?}.each ...

I am sure there must be a way to get the database to do this in one query, eg:

SELECT * FROM
POD_ADMINS
    WHERE POD_ID IN
   (SELECT ID FROM PODS WHERE <condition>)

<condition> = this would be the is_active? method of the Pod class.

I know I could write the sql and pass that but I want to access/use the 'is_active?' method on the Pod class in this logic - because if that method changes (it probably will) I don't want to have to refactor this as well.

I am sure there must be some simple way to achieve what I want and only have one query hit the database?

For completeness, here is the 'is_active?' method:

  def is_active?
    return true if (self.inactive_date.blank? || self.days_left > 0)
    return false
  end

which depends upon:

  def days_left
    days = self.inactive_date.strftime("%j").to_i - Date.today.strftime("%j").to_i unless self.inactive_date.nil?
    return 0 if days < 0
    return days
  end

EDIT

Models:

class Pod
  has_one :pod_admin
  has_many :parents
end

class PodAdmin
  belongs_to :pod
end

Solution

  • Just try:

    pod_admins = PodAdmin.includes(:pod).where("pod_id IS NOT null").select{|pa| pa if pa.pod.is_active?}
    

    it will only produces two SQL like:

     SELECT  "pod_admins".* FROM "pod_admins" WHERE ("pod_id IS NOT null")
    

    and

    SELECT "pods".* FROM "pods" WHERE "pods"."id" IN (x, y, z,....)