refactoring polymorphic actions
Hi Chris! I implemented the notification system based on your video with the partials. Works perfectly. I've got some problem though when user wanna check out the notification. When he/she clicks on the notification (either in dropdown or notification page) the following things must happen:
- the checked_at attr gets set to current time (same for all types of notification)
- the unchecked notification number gets decreased by 1 (same for all types of notification)
- user gets redirected where the notification action happened (different for all types of notification)
At the moment I link every type of notification action (commented, accepted, etc.) to the custom checking_decreasing
action route where first checked_at
gets set and unchecked notification number gets decreased. Then based on the notification.notifiable_type
and notification.action
I redirect them to the desired page. So if sby commented on product then by clicking the notification you will get on that page. But as you see below there are so many combinations for redirecting that things got pretty messy in no time.
What kinda refactoring approach would you take here? I was thinking about creating a NotificationRedirectionsController
where every notification_action
+ notifiable_type
combination would have a separate action like def product_commented
or def team_invitation_accepted
etc. Is that a good idea? Do you know any refactoring technique for this case?
_commented.html.erb (same link in _commented.json.jbuilder
<%= link_to checking_decreasing_user_notifications_path(current_user,
notifiable_type: notification.notifiable_type,
notifiable_id: notification.notifiable_id,
notification_action: notification.action
) do %>
notifications controller / custom action
def checking_decreasing
current_user.decreasing_comment_notification_number(params[:notifiable_type],
params[:notifiable_id]
)
redirect_to notification_redirection_path(params[:notifiable_type],
params[:notifiable_id],
params[:notification_action]
)
end
application controller
def notification_redirection_path(notifiable_type, notifiable_id, action)
if action == "commented"
if notifiable_type == "ProductCustomer"
product_customer = ProductCustomer.find(notifiable_id)
product_id = product_customer.product_id
elsif notifiable_type == "ProductLead"
product_lead = ProductLead.find(notifiable_id)
product_id = product_lead.product_id
end
route = case notifiable_type
when "Post"
posts_path(anchor: "post_#{notifiable_id}")#{}"/posts#post_#{notifiable_id}"
when "Product"
product_path(notifiable_id, anchor: "comment-panel")#/products/#{notifiable_id}#comment-panel"
when "ProductLead"
product_product_lead_path(product_id, notifiable_id, anchor: "comment-panel")#{}"/products/#{product_id}/#{notifiable_type}/#{notifiable_id}#comment-panel"
when "ProductCustomer"
product_product_customer_path(product_id, notifiable_id, anchor: "comment-panel") #/products/#{product_id}/#{notifiable_type}/#{notifiable_id}#comment-panel"
end
elsif action == "invited"
if notifiable_type == "Product"
product_path(notifiable_id, anchor: "product-invitation-well")
elsif notifiable_type == "ProductCustomer"
product_customer = ProductCustomer.find(notifiable_id)
product_id = product_customer.product_id
product_product_customer_path(product_id, notifiable_id)
end
elsif action == "accepted"
if notifiable_type == "Product" #team member invitation
product_product_owner_panels_path(notifiable_id)
elsif notifiable_type == "ProductCustomer" #referencer invitation
product_customer = ProductCustomer.find(notifiable_id)
product_id = product_customer.product_id
product_product_owner_panels_path(product_id)
end
end
end