All threads / refactoring polymorphic actions

Ask A Question

Notifications

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
  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
Join the discussion

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

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

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

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2020 GoRails, LLC. All rights reserved.