* Add ProMembership model * Implement ProMembershipsController#create * Implement basic ProMembershipsController#show * Add ProMembership to ledger * Populate user history after pro subscription is created * Add fields for expiration notifications * Add ProMemberships::ExpirationNotifier to notify users of expiring memberships * Add tasks for recurring jobs to notify users of expiration * Add auto_recharge column to ProMembership * Add ProMemberships::Biller (incomplete) * Fix specs * Add ProMembership to Administrate * Fix spec * Add has_enough_credits? to User and Organization * Add Payments::Customer class * Finish ProMembership::Biller functionality * Fix ProMemberships::Creator check for credits * Disable destroy actions for ProMembershipsController * Correctly authenticate ProMembershipsController actions * Make sure only pro user's history can be indexed * Add ProMembershipsController#update action for auto recharge * Use regular AR to save new credits and add touch to the purchaser * Clarify Pro membership create policy * Display information about an existing pro membership * Add UI to show page * Add system test for Pro membership creation * Implement edit membership * Make sure users with pro memberships can access history and dashboard pro * Fix padding issue * Show a different text for a user that has credits but not enough for Pro * Move Pro Membership functionality inside settings * Update Pro Membership link in email notifications * Bust all relevant caches * Add the Pro checkmark around the website * Use Users::ResaveArticlesJob instead of delay * Add/remove user from pro-members chat channel * Use the appropriate Pro checkmark * Remove unfinished pro elements * Remove checkmark JS
51 lines
1.4 KiB
Ruby
51 lines
1.4 KiB
Ruby
class ArticleSuggester
|
|
def initialize(article)
|
|
@article = article
|
|
end
|
|
|
|
def articles(max: 4)
|
|
if article.tag_list.any?
|
|
# avoid loading more data if we don't need to
|
|
tagged_suggestions = suggestions_by_tag(max: max)
|
|
return tagged_suggestions if tagged_suggestions.size == max
|
|
|
|
# if there are not enough tagged articles, load other suggestions
|
|
# ignoring tagged articles that might be relevant twice, hence avoiding duplicates
|
|
num_remaining_needed = max - tagged_suggestions.size
|
|
other_articles = other_suggestions(
|
|
max: num_remaining_needed,
|
|
ids_to_ignore: tagged_suggestions.pluck(:id),
|
|
)
|
|
tagged_suggestions.union(other_articles)
|
|
else
|
|
other_suggestions(max: max)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :article
|
|
|
|
def other_suggestions(max: 4, ids_to_ignore: [])
|
|
ids_to_ignore << article.id
|
|
Article.published.where(featured: true).
|
|
where.not(id: ids_to_ignore).
|
|
order("hotness_score DESC").
|
|
includes(user: [:pro_membership]).
|
|
offset(rand(0..offsets[1])).
|
|
first(max)
|
|
end
|
|
|
|
def suggestions_by_tag(max: 4)
|
|
Article.published.tagged_with(article.tag_list, any: true).
|
|
where.not(id: article.id).
|
|
order("hotness_score DESC").
|
|
includes(user: [:pro_membership]).
|
|
offset(rand(0..offsets[0])).
|
|
first(max)
|
|
end
|
|
|
|
def offsets
|
|
Rails.env.production? ? [10, 120] : [0, 0]
|
|
end
|
|
end
|