diff options
Diffstat (limited to 'app/models/users/in_product_marketing_email.rb')
-rw-r--r-- | app/models/users/in_product_marketing_email.rb | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/app/models/users/in_product_marketing_email.rb b/app/models/users/in_product_marketing_email.rb index f2f1d18339e..82c2e336a09 100644 --- a/app/models/users/in_product_marketing_email.rb +++ b/app/models/users/in_product_marketing_email.rb @@ -4,15 +4,28 @@ module Users class InProductMarketingEmail < ApplicationRecord include BulkInsertSafe + BUILD_IOS_APP_GUIDE = 'build_ios_app_guide' + CAMPAIGNS = [BUILD_IOS_APP_GUIDE].freeze + belongs_to :user validates :user, presence: true - validates :track, presence: true - validates :series, presence: true + + validates :track, :series, presence: true, if: -> { campaign.blank? } + validates :campaign, presence: true, if: -> { track.blank? && series.blank? } + validates :campaign, inclusion: { in: CAMPAIGNS }, allow_nil: true + validates :user_id, uniqueness: { scope: [:track, :series], - message: 'has already been sent' - } + message: 'track series email has already been sent' + }, if: -> { track.present? } + + validates :user_id, uniqueness: { + scope: :campaign, + message: 'campaign email has already been sent' + }, if: -> { campaign.present? } + + validate :campaign_or_track_series enum track: { create: 0, @@ -31,23 +44,47 @@ module Users INACTIVE_TRACK_NAMES = %w(invite_team).freeze ACTIVE_TRACKS = tracks.except(*INACTIVE_TRACK_NAMES) + scope :for_user_with_track_and_series, -> (user, track, series) do + where(user: user, track: track, series: series) + end + scope :without_track_and_series, -> (track, series) do - users = User.arel_table - product_emails = arel_table + join_condition = for_user.and(for_track_and_series(track, series)) + users_without_records(join_condition) + end + + scope :without_campaign, -> (campaign) do + join_condition = for_user.and(for_campaign(campaign)) + users_without_records(join_condition) + end - join_condition = users[:id].eq(product_emails[:user_id]) - .and(product_emails[:track]).eq(ACTIVE_TRACKS[track]) - .and(product_emails[:series]).eq(series) + def self.users_table + User.arel_table + end - arel_join = users.join(product_emails, Arel::Nodes::OuterJoin).on(join_condition) + def self.distinct_users_sql + name = users_table.table_name + Arel.sql("DISTINCT ON(#{name}.id) #{name}.*") + end + def self.users_without_records(condition) + arel_join = users_table.join(arel_table, Arel::Nodes::OuterJoin).on(condition) joins(arel_join.join_sources) .where(in_product_marketing_emails: { id: nil }) - .select(Arel.sql("DISTINCT ON(#{users.table_name}.id) #{users.table_name}.*")) + .select(distinct_users_sql) end - scope :for_user_with_track_and_series, -> (user, track, series) do - where(user: user, track: track, series: series) + def self.for_user + arel_table[:user_id].eq(users_table[:id]) + end + + def self.for_campaign(campaign) + arel_table[:campaign].eq(campaign) + end + + def self.for_track_and_series(track, series) + arel_table[:track].eq(ACTIVE_TRACKS[track]) + .and(arel_table[:series]).eq(series) end def self.save_cta_click(user, track, series) @@ -55,5 +92,13 @@ module Users email.update(cta_clicked_at: Time.zone.now) if email && email.cta_clicked_at.blank? end + + private + + def campaign_or_track_series + if campaign.present? && (track.present? || series.present?) + errors.add(:campaign, 'should be a campaign or a track and series but not both') + end + end end end |