Skip to content

Instantly share code, notes, and snippets.

@delbetu
Last active March 22, 2019 23:20
Show Gist options
  • Save delbetu/368bd400748e5649c128dec04eee7e30 to your computer and use it in GitHub Desktop.
Save delbetu/368bd400748e5649c128dec04eee7e30 to your computer and use it in GitHub Desktop.
Isolating from rails
class BarService
def foo(input_data)
...
if input_data.page
num = 45
output_data.notified_at_offset = notification_data_access.notified_at(input_data.page)
else
num = 10
end
output_data.notifications =
if input_data.filter.to_s.casecmp("posts").zero?
notification_data_access.published_articles_for(user_id: output_data.user.id)
elsif input_data.filter.to_s.casecmp("comments").zero?
notification_data_access.comments_or_mentions_for(user_id: output_data.user.id)
else
notification_data_access.notifications_for_user(user_id: output_data.user.id)
end
...
end
end
class Notification < ApplicationRecord
class << self
def notified_at(page_number)
find(page_number)&.notified_at
end
def published_articles_for(user_id:)
where(user_id: user_id, notifiable_type: "Article", action: "Published")
.order("notified_at DESC")
end
def comments_or_mentions_for(user_id:)
where(user_id: user_id, notifiable_type: "Comment", action: nil).or(
where(user_id: user_id, notifiable_type: "Mention")
).order("notified_at DESC")
end
def notifications_for_user(user_id:)
where(user_id: user_id).order("notified_at DESC")
end
end
end
# Move foo method to new Bar class
class Bar
def foo(input_data)
output_data = OpenStruct.new(
notifications_index: -1,
user: nil,
notified_at_offset: nil,
notifications: [],
last_user_reaction: '',
last_user_comment: ''
)
if input_data.user_signed_in?
output_data.notifications_index = true
output_data.user =
if input_data.username && input_data.current_user.admin?
User.find_by_username(input_data.username)
else
input_data.current_user
end
if input_data.page
num = 45
output_data.notified_at_offset = Notification.find(input_data.page)&.notified_at
else
num = 10
end
output_data.notifications =
if input_data.filter.to_s.casecmp("posts").zero?
Notification.where(user_id: output_data.user.id, notifiable_type: "Article", action: "Published").
order("notified_at DESC")
elsif input_data.filter.to_s.casecmp("comments").zero?
Notification.where(user_id: output_data.user.id, notifiable_type: "Comment", action: nil). # Nil action means not reaction in this context
or(Notification.where(user_id: output_data.user.id, notifiable_type: "Mention")).
order("notified_at DESC")
else
Notification.where(user_id: output_data.user.id).
order("notified_at DESC")
end
output_data.last_user_reaction = output_data.user.reactions.last&.id
output_data.last_user_comment = output_data.user.comments.last&.id
output_data.notifications = output_data.notifications.where("notified_at < ?", output_data.notified_at_offset) if output_data.notified_at_offset
output_data.notifications = NotificationDecorator.decorate_collection(output_data.notifications.limit(num))
end
output_data
end
end
class NotificationsController < ApplicationController
# No authorization required because we provide authentication on notifications page
def index
input_data = OpenStruct.new(
user_signed_in?: user_signed_in?,
username: params[:username],
current_user: current_user,
page: params[:page],
filter: params[:filter]
)
collaborator = Bar.new
output = collaborator.foo(input_data)
@notifications_index = output.notifications_index
@user = output.user
@notifications = output.notifications
@last_user_reaction = output.last_user_reaction
@last_user_comment = output.last_user_comment
render partial: "notifications_list" if output.notified_at_offset
end
end
# Create input_data and output_data objects
class NotificationsController < ApplicationController
# No authorization required because we provide authentication on notifications page
def index
input_data = OpenStruct.new(
user_signed_in?: user_signed_in?,
username: params[:username],
current_user: current_user,
page: params[:page],
filter: params[:filter]
)
output = foo(input_data)
@notifications_index = output.notifications_index
@user = output.user
@notifications = output.notifications
@last_user_reaction = output.last_user_reaction
@last_user_comment = output.last_user_comment
render partial: "notifications_list" if output.notified_at_offset
end
def foo(input_data)
output_data = OpenStruct.new(
notifications_index: -1,
user: nil,
notified_at_offset: -1,
notifications: [],
last_user_reaction: '',
last_user_comment: ''
)
if input_data.user_signed_in?
output_data.notifications_index = true
output_data.user =
if input_data.username && input_data.current_user.admin?
User.find_by_username(input_data.username)
else
input_data.current_user
end
if input_data.page
num = 45
output_data.notified_at_offset = Notification.find(input_data.page)&.notified_at
else
num = 10
end
output_data.notifications =
if input_data.filter.to_s.casecmp("posts").zero?
Notification.where(user_id: output_data.user.id, notifiable_type: "Article", action: "Published").
order("notified_at DESC")
elsif input_data.filter.to_s.casecmp("comments").zero?
Notification.where(user_id: output_data.user.id, notifiable_type: "Comment", action: nil). # Nil action means not reaction in this context
or(Notification.where(user_id: output_data.user.id, notifiable_type: "Mention")).
order("notified_at DESC")
else
Notification.where(user_id: output_data.user.id).
order("notified_at DESC")
end
output_data.last_user_reaction = output_data.user.reactions.last&.id
output_data.last_user_comment = output_data.user.comments.last&.id
output_data.notifications = output_data.notifications.where("notified_at < ?", output_data.notified_at_offset) if output_data.notified_at_offset
output_data.notifications = NotificationDecorator.decorate_collection(output_data.notifications.limit(num))
end
output_data
end
end
class NotificationsController < ApplicationController
# No authorization required because we provide authentication on notifications page
def index
input_data =
BarService::InputData.new(user_signed_in?, params[:username], current_user, params[:page], params[:filter])
collaborator = BarService.new
output = collaborator.foo(input_data)
...
end
end
# Renamed and moved to app/services
class BarService
InputData = Struct.new(:user_signed_in?, :username, :current_user, :page, :filter)
OutputData = Struct.new(:notifications_index, :user, :notified_at_offset,
:notifications, :last_user_reaction, :last_user_comment)
attr_reader :notification_data_access, :user_data_access
def initialize(notification_data_access: Notification, user_data_access: User)
@notification_data_access = notification_data_access
@user_data_access = user_data_access
end
def foo(input_data)
output_data = OutputData.new(-1, nil, nil, [], '', '')
if input_data.user_signed_in?
...
end
output_data
end
end
class BarService
def foo(input_data)
...
output_data.notifications = output_data.notifications.filter_by_notified_at(output_data.notified_at_offset)
...
end
end
class Notification < ApplicationRecord
class << self
...
def filter_by_notified_at(notified_at_offset)
if notified_at_offset
where("notified_at < ?", notified_at_offset)
else
self
end
end
end
end
class Bar
attr_reader :notification_data_access, :user_data_access
def initialize(notification_data_access: Notification, user_data_access: User)
@notification_data_access = notification_data_access
@user_data_access = user_data_access
end
def foo(input_data)
output_data = OpenStruct.new(
notifications_index: -1,
user: nil,
notified_at_offset: nil,
notifications: [],
last_user_reaction: '',
last_user_comment: ''
)
if input_data.user_signed_in?
output_data.notifications_index = true
output_data.user =
if input_data.username && input_data.current_user.admin?
user_data_access.find_by_username(input_data.username)
else
input_data.current_user
end
if input_data.page
num = 45
output_data.notified_at_offset = notification_data_access.find(input_data.page)&.notified_at
else
num = 10
end
output_data.notifications =
if input_data.filter.to_s.casecmp("posts").zero?
notification_data_access.where(user_id: output_data.user.id, notifiable_type: "Article", action: "Published").
order("notified_at DESC")
elsif input_data.filter.to_s.casecmp("comments").zero?
notification_data_access.where(user_id: output_data.user.id, notifiable_type: "Comment", action: nil). # Nil action means not reaction in this context
or(notification_data_access.where(user_id: output_data.user.id, notifiable_type: "Mention")).
order("notified_at DESC")
else
notification_data_access.where(user_id: output_data.user.id).
order("notified_at DESC")
end
output_data.last_user_reaction = output_data.user.reactions.last&.id
output_data.last_user_comment = output_data.user.comments.last&.id
output_data.notifications = output_data.notifications.where("notified_at < ?", output_data.notified_at_offset) if output_data.notified_at_offset
output_data.notifications = NotificationDecorator.decorate_collection(output_data.notifications.limit(num))
end
output_data
end
end
class NotificationsController < ApplicationController
# No authorization required because we provide authentication on notifications page
def index
input_data = OpenStruct.new(
user_signed_in?: user_signed_in?,
username: params[:username],
current_user: current_user,
page: params[:page],
filter: params[:filter]
)
collaborator = Bar.new
output = collaborator.foo(input_data)
@notifications_index = output.notifications_index
@user = output.user
@notifications = output.notifications
@last_user_reaction = output.last_user_reaction
@last_user_comment = output.last_user_comment
render partial: "notifications_list" if output.notified_at_offset
end
end
# Before
if input_data.page
num = 45
output_data.notified_at_offset = notification_data_access.notified_at(input_data.page)
else
num = 10
end
# After
if input_data.page
num = 45
else
num = 10
end
if input_data.page
output_data.notified_at_offset = notification_data_access.notified_at(input_data.page)
end
# Rename num to number_of_notifications
# Before
class Bar
def foo(input_data)
...
if input_data.user_signed_in?
do_stuff
end
output_data
end
end
# After
class Bar
def foo(input_data)
...
return output_data unless input_data.user_signed_in?
do_stuff
output_data
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment