docbrown/app/services/articles/updater.rb

66 lines
2.2 KiB
Ruby

module Articles
class Updater
def initialize(user, article_id, article_params, event_dispatcher = Webhook::DispatchEvent)
@user = user
@article_id = article_id
@article_params = article_params
@event_dispatcher = event_dispatcher
end
def self.call(*args)
new(*args).call
end
def call
article = load_article
was_published = article.published
# the client can change the series the article belongs to
if article_params.key?(:series)
series = article_params[:series]
article.collection = Collection.find_series(series, article.user) if series.present?
article.collection = nil if series.nil?
end
# convert tags from array to a string
tags = article_params[:tags]
if tags.present?
article_params[:tag_list] = tags.join(", ")
article_params.delete(:tags)
end
# updated edited time only if already published and not edited by an admin
update_edited_at = article.user == user && article.published
article_params[:edited_at] = Time.current if update_edited_at
article.update!(article_params)
# send notification only the first time an article is published
send_notification = article.published && article.saved_change_to_published_at.present?
Notification.send_to_followers(article, "Published") if send_notification
# remove related notifications if unpublished
if article.saved_changes["published"] == [true, false]
Notification.remove_all_by_action_without_delay(notifiable_ids: article.id, notifiable_type: "Article", action: "Published")
Notification.remove_all(notifiable_ids: article.comments.pluck(:id), notifiable_type: "Comment") if article.comments.exists?
end
# don't send only if article keeps being unpublished
dispatch_event(article) if article.published || was_published
article.decorate
end
private
attr_reader :user, :article_id, :article_params, :event_dispatcher
def dispatch_event(article)
event_dispatcher.call("article_updated", article)
end
def load_article
relation = user.has_role?(:super_admin) ? Article.includes(:user) : user.articles
relation.find(article_id)
end
end
end