0

I have a query to find properties by a certain criteria. I'm including the Users table in the query so I can have access to the property owner (user_id) and send them an email about the property.

@testproperties.users.each do |property|
  UserMailer.with(property: property, user: property.user).check_listing.deliver
  property.update_columns(property_reminder_date: Time.now )
end

This works fine, except since I'm looping through properties, if a user has more than 1 property, they will receive X amount of emails. I want to bundle this by users.

So if a user has 2 properties, I want to send the mailer the user and their multiple properties. they will receive 1 email instead of two. and the email view will be fed an array of properties.

But I'm not sure how to do this. I need to loop over users and have their properties connected to them.

Edit:

if I do a query like:

      @testusers = User.joins(:properties)
      .where("properties.updated_at < :date", date: 30.days.ago)
      .where("properties.property_reminder_date < :date OR properties.property_reminder_date IS NULL", date: 30.days.ago)
      .where('properties.id NOT IN (SELECT DISTINCT(property_id) FROM transactions)')

This will give me the users I need to email to, however, accessing each user's properties shows ALL properties rather than the ones I need based on my SQL queries.

Edit again:

I was able to achieve what I wanted in a really messy way:

      @testusers = User.joins(:properties)
      .where("properties.updated_at < :date", date: 30.days.ago)
      .where("properties.property_reminder_date < :date OR properties.property_reminder_date IS NULL", date: 30.days.ago)
      .where('properties.id NOT IN (SELECT DISTINCT(property_id) FROM transactions)')
      @testusers = @testusers.uniq

      @testusers.each do |user|
        propertyList = user.properties.active.has_not_updated
        UserMailer.with(properties: propertyList, user: user).check_listing.deliver
        propertyList.each do |property|
          property.update_columns(property_reminder_date: Time.now )
        end
      end

Property model:

...
   scope :active, -> { where('expires_at >= ?', Time.now) }
  scope :has_not_updated, -> {active.where("updated_at < :date", date: 30.days.ago).where("property_reminder_date < :date OR property_reminder_date IS NULL", date: 30.days.ago).where('id NOT IN (SELECT DISTINCT(property_id) FROM transactions)') }

1 Answer 1

1

You can do something like:

properties.group_by(&:user).each do |user,  properties|
  UserMailer.send_email(user, properties).deliver_later
end

In each iteration you will have user and array of user's properties.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you. that's much cleaner than what I came up with. I realize I forgot to include some code in my question. resulted in downvotes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.