How to access Spree's link_to_cart function from main rails app
Asked Answered
M

5

5

I am building a spree shop into an exiting Rails application, and I need to access link_to_cart from outside of the Spree engine.

link_to_cart can be found here: spree/core/app/helpers/spree/base_helper.rb

Since I have modified the styling in link_to_cart, I also created:

  #helpers/spree/base_helper_decorator.rb
  module Spree
    module BaseHelper
      def link_to_cart(text = nil)
      text = text ? h(text) : Spree.t('cart')
      css_class = nil

      if simple_current_order.nil? or simple_current_order.item_count.zero?
        text = "#{text}: (#{Spree.t('empty')})"
        css_class = 'empty'
      else
        text = "<i class='fa fa-shopping-cart'></i> #{text}: (#{simple_current_order.item_count})  <span class='amount'>#{simple_current_order.display_total.to_html}</span>".html_safe
        css_class = 'full'
      end

      link_to text.html_safe, spree.cart_path, :class => "cart-info #{css_class} btn btn-small btn-success pull-right", style: "margin-left:10px;"
    end
  end
end

I have tried doing stuff like Spree::BaseHelper.link_to_cart outside of the engine, but I keep getting undefined local variable or method 'link_to_cart'

I found this on a different StackOverflow question, and it seems promising, but I'm not sure how to modify it for my needs:

module MyEngine
  class Engine < Rails::Engine
    initializer 'my_engine.action_controller' do |app|
      ActiveSupport.on_load :action_controller do
        helper MyEngine::ImportantHelper
      end
    end
  end
end
Medea answered 13/8, 2014 at 22:3 Comment(1)
Hi @Medea , I have the same problem but the solution wont work for me. Any tip?Haye
M
7

Ok, thanks Ben for getting me on the right track. Here was my solution:

# class ApplicationController < ActionController::Base
   include Spree::Core::ControllerHelpers::Order
   include Spree::Core::ControllerHelpers::Auth
   helper Spree::BaseHelper
   helper Spree::StoreHelper

Update

I ran into an issue with current_store being undefined outside of the engine. I'm not sure how to solve this properly, but in the meantime I've just added the following to stop spree from calling current_store:

module Spree
  module Core
    module ControllerHelpers
      module Order
        def current_order_params
          { currency: current_currency, guest_token: cookies.signed[:guest_token], store_id: Spree::Store.first, user_id: try_spree_current_user.try(:id) }
        end
      end
    end
  end
end

Also helper Spree::StoreHelper seems to no longer be required to display the cart button and current orders..

Medea answered 1/9, 2014 at 17:55 Comment(5)
Ahha, the fabled stackoverflow answer with the exact answer you needed! Where did you add the second code snippet please? I tried orders controller decorator but no cigar :(Ashe
Cannot recall. Try libMedea
Hmm no luck. Tried various combinations within app and no luck too. How strange.Ashe
Adding the current_order_params function to the application controller and manually specifying current_currency is working for me for now!Ashe
Thanks for this! It got me on the right track. It seems some updates to spree made it so you have to add include Spree::Core::ControllerHelpers::Common . This changes the way your entire app is rendered, though.Southernly
A
2

You need to do two things

  1. Create your override
  2. Make your override accessible within the main app

Step 1: My Spree overrides are in the overrides folder in my main app. The override should call module_eval on the module that you are decorating.

#overrides/base_helper_decorator.rb
Spree::BaseHelper.module_eval do

  def link_to_cart(text = nil)
    #Your customizations here
  end

end

Step 2: Add one of the lines below to your main app ApplicationController to access your decorated helper.

helper_method :link_to_cart # Add only the link_to_cart method 

helper 'spree/base'         # Add all methods (your decoration plus the default methods) 
                            # from the Spree BaseHelper module to your main app
Adenoid answered 1/9, 2014 at 11:58 Comment(1)
Not sure why, but after doing everything I am still getting undefined local variable or method `link_to_cart'Medea
S
2

There have been some updates since Abram left his answer. It got me on the right track but I had a few hiccups. The main one was current_currency being undefined.

application_controller.rb

class ApplicationController < ActionController::Base
  include Spree::Core::ControllerHelpers::Order
  include Spree::Core::ControllerHelpers::Auth
  include Spree::Core::ControllerHelpers::Store
  include Spree::Core::ControllerHelpers::Common
  helper Spree::BaseHelper

I overrode the Spree navbar and used the one for my main app.

It started working when I added include Spree::Core::ControllerHelpers::Common. Unfortunately, this renders all views through the spree spree_application.html.erb layout. You may have to override and tinker a bit with this view.

Also, all of the css comes from spree at this point. You'll have to move your custom css into the spree namespace and @import it.

Southernly answered 29/12, 2016 at 21:41 Comment(0)
Z
1

You will have to include the right helpers in your main application outside the engine too. In the upcoming version 3.2.0 of spree I just had to add:

# class ApplicationController < ActionController::Base
  include Spree::Core::ControllerHelpers::Store
  include Spree::Core::ControllerHelpers::Order
  include Spree::Core::ControllerHelpers::Auth

to my ApplicationController to make link_to_cart work everywhere. You'll need to include more then one helper class, because for example current_store (used by other helpers) is defined in Spree::Core::ControllerHelpers::Store, so add that too to get rid of any errors.

Zuzana answered 25/7, 2016 at 13:47 Comment(0)
A
0

You can add this to your main_app to access the cart.

<%= link_to "Cart", spree.cart_path %>

Astrometry answered 22/10, 2015 at 0:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.