Reputation: 41914
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
Upvotes: 5
Views: 1453
Reputation: 541
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.
Upvotes: 2
Reputation: 4982
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.
Upvotes: 1
Reputation: 51
You can add this to your main_app to access the cart.
<%= link_to "Cart", spree.cart_path %>
Upvotes: 0
Reputation: 41914
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..
Upvotes: 7
Reputation: 2630
You need to do two things
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
Upvotes: 2