Ruby on Rails : activerecord クエリから配列を作成
概要
特定の基準で物件を検索するクエリがあります。プロパティの所有者 (user_id) にアクセスして、プロパティに関する電子メールを送信できるように、クエリに Users テーブルを含めています。
@testproperties.users.each do |property|
UserMailer.with(property: property, user: property.user).check_listing.deliver
property.update_columns(property_reminder_date: Time.now )
end
これは正常に機能しますが、プロパティをループしているため、ユーザーが複数のプロパティを持っている場合、X 通の電子メールを受信することになります。これをユーザーごとにバンドルしたいと考えています。
したがって、ユーザーが 2 つのプロパティを持っている場合、メーラーにユーザーとその複数のプロパティを送信したいと考えています。電子メールは 2 通ではなく 1 通受信されます。電子メール ビューにはプロパティの配列が供給されます。
しかし、どうすればよいのかわかりません。ユーザーをループし、ユーザーのプロパティをユーザーに接続する必要があります。
編集:
次のようなクエリを実行すると:
@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)')
これにより、電子メールを送信する必要があるユーザーが得られますが、各ユーザーのプロパティにアクセスすると、SQL クエリに基づいて必要なプロパティではなく、すべてのプロパティが表示されます。
再度編集します:
本当に厄介な方法で私が望んでいたものを達成することができました。
@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
プロパティモデル:
...
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)') }
解決策
次のようなことができます。
properties.group_by(&:user).each do |user, properties|
UserMailer.send_email(user, properties).deliver_later
end
各反復で、ユーザーとユーザーのプロパティの配列が得られます。