docbrown/app/models/user_subscription.rb
Alex 8714a36d27
[deploy] User subscriptions API and backend updates (#8779)
* Create "blank" EmailSubscriptionTag

* Refactor liquid_tags_used with spec

* Create /user_subscriptions#create

- Update liquid tag name to UserSubscriptionTag

* Add rate limiting and specs

* Add counter_culture for user_subscriptions

* Update /async_info/base_data

- Alphabetize user_data
- Add email
- Add subscription_source_article_ids
- Cache subscription_source_article_ids on User model

* Add stale email check and specs

* Change user_email to subscriber_email for clarity

* Restrict UserSubscriptionTag

* Rename RESTRICTED_TAGS to RESTRICTED_LIQUID_TAGS

* Make TODO comment more clear

* Refactor error responses and update specs

* Update type to source_type in error message

* Use constantize over safe_constantize

* Add check for active source

* Refactor checking of current_user's subscriptions

- Remove data from async_info
- Create a new service to fetch/cache a user's existing subscriptions

* Restrict email in base_data to admin roles

* Oops! Rename liquid tag file

* Change error back to result...oops!

* It's not goodbye, it's see you later. RIP email :/

* Add current_email to /user_subscriptions/base_data

* Revert adding current_email

* Undo async_info_controller changes/fix conflict

* Move params to constant

* Refactor SubscriptionCacheChecker

* Remove duplicate status code in JSON response

* Remove duplicate status code for #subscribed

* Use response.parsed_body

* Remove user guard in SubscriptionCacheChecker
2020-06-23 13:43:32 -04:00

35 lines
1.4 KiB
Ruby

# This model handles a user (subscriber) subscribing to another user (author).
# We also record the source of the subscription (Article, Comment, etc.) via a
# polymorphic association (user_subscription_source/able).
class UserSubscription < ApplicationRecord
ALLOWED_TYPES = %w[Article].freeze
counter_culture :subscriber, column_name: "subscribed_to_user_subscriptions_count"
belongs_to :author, class_name: "User", inverse_of: :source_authored_user_subscriptions
belongs_to :subscriber, class_name: "User", inverse_of: :subscribed_to_user_subscriptions
belongs_to :user_subscription_sourceable, polymorphic: true
validates :author_id, presence: true
validates :subscriber_email, presence: true
validates :subscriber_id, presence: true, uniqueness: { scope: %i[subscriber_email user_subscription_sourceable_type user_subscription_sourceable_id] }
validates :user_subscription_sourceable_id, presence: true
validates :user_subscription_sourceable_type, presence: true, inclusion: { in: ALLOWED_TYPES }
def self.build(source:, subscriber:)
new(build_attributes(source, subscriber))
end
def self.make(source:, subscriber:)
create(build_attributes(source, subscriber))
end
def self.build_attributes(source, subscriber)
{
user_subscription_sourceable: source,
author_id: source&.user_id,
subscriber_id: subscriber&.id,
subscriber_email: subscriber&.email
}
end
end