Search code examples
ruby-on-railsbusiness-logicrole-base-authorization

Rails 4 Business Logic, Authorization - Updating Prices based on Authentication


I have a super basic ecommerce app with a User model authenticated with Omniauth, Product model with name and price, and ShoppingCart and ShoppingCartItem models (utilizing the acts_as_shopping_cart gem).

My issue is when I have a user authenticate through an Omniauth provider, I want to provide discounts based on who they authenticate with.

Let's say they sign in with facebook - then I want to provide a 20% discount for them. I'm not sure how to go about this actually - I think I want to write this business logic in my Product and ShoppingCartItem models, setting something like

def self.price 
  if current_user.provider == 'facebook'
    super * 0.8 
  else
    super
end

but I can't access current_user within the models because it is set by the session.

Should I do it in the controller where I have access to current_user? Then I'd have to open the Product and ShoppingCartItem classes within the controllers to override their price methods which all feels wrong and frankly I don't know if it will even work.


Solution

  • I changed my strategy a bit. I decided to create a method to override the total method on my shoppingcart instance. I didn't want to change the prices, I just applied the discount to the total like you would see at the checkout view.

    I created an instance method in the model shopping_cart.rb like so:

    def discount(user)
      if user && user.provider == 'facebook'
        def total
          super * 0.8
        end
      else
        def total
          super
        end
      end
    end
    

    Then I can call this method in the controller and pass in current_user there.

    shopping_carts_controller.rb

    def show
      @shopping_cart.discount(current_user)
    end
    

    And in the view I just have @shopping_cart.total where the total method is overriden based on the user's oauth provider!