Ask A Question


You’re not receiving notifications from this thread.

refactoring polymorphic actions

Sean M asked in General

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
  redirect_to notification_redirection_path(params[:notifiable_type],

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
    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"
  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)
  elsif action == "accepted"
    if notifiable_type == "Product" #team member invitation
    elsif notifiable_type == "ProductCustomer" #referencer invitation
      product_customer = ProductCustomer.find(notifiable_id)
      product_id = product_customer.product_id
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 84,387+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.