0

Good evening all,

I've been trying to solve this for a while, I'm positive its something very simple that I'm missing...

I currently have a web store, it allows customers to add products to a cart, which then allows customers to pay via PayPal.

There are no problems if i attempt to pay from 'within' a cart, E.G

http://localhost:3000/carts/1

However, I've created a partial which shows all cart items (this partial shows within a drop-down from the navigation bar), and from within this drop-down a customer should be able to click 'checkout'. With the aim that it works in the same way as going into the cart; it should take them straight to PayPal to pay. This partial is below.

_display_cart.htlm.erb

<% current_cart.line_items.each do |item| %>
 <li> <%= item.product.title %>  
 <%=  number_to_currency item.product.price , :unit =>"&pound" %> &times; <%= item.quantity %> </li>
<% end %>

<div align="right">
 <%= number_to_currency(current_cart.grand_total,  :unit => "&pound;") %>&nbsp;
</div>
 </ul>
<%= link_to "Checkout", @cart.paypal_url(products_url) %>

If i add an item to the cart from a products show page, while the following is in place:

<%= link_to "Checkout", @cart.paypal_url(products_url) %> 

I get an undefined method error:

undefined method `paypal_url' for nil:NilClass

Yet paypal_url is defined in cart.rb, as follows.

    def paypal_url(return_url)
values = {
:business => 'EMAIL',
:upload => 1,
:return => return_url,
:invoice => id
}
line_items.each_with_index do |item, index|
values.merge!({
  "amount_#{index+1}" => item.product.price,
  "item_name_#{index+1}" => item.product.title,
  "item_number_#{index+1}" => item.id,
  "quantity_#{index+1}" => item.quantity
})
end
"https://www.sandbox.paypal.com/cgi-bin/webscr?" + values.to_query
end

Interestingly, if i go into localhost:3000/carts/1 the drop down from my navigation bar works perfectly and the error no longer blocks my way to the site. The checkout button within the nav bar drop-down then takes me to PayPal as it should; it's just not doing that on the rest of the site, only within the cart views (show only, not index).

Please forgive me if it's going to be as simple as i presume it will, it's been some months since i had a play with rails, and i wasn't that great to begin with!

1 Answers1

1

You are getting the error because @cart is not set. Currently, its value is nil within the partial _display_cart.html.erb. Make sure that you set the value of @cart before rendering this partial.

For example:

Set the value of @cart in the action which renders the complete page (within which you are rendering the partial).

Pass @cart through locals while rendering the partial:

<%= render :partial => 'display_cart', :locals => {:cart => @cart} %>

and in the partial access it as cart instead of @cart.

UPDATE

OP wanted to checkout current cart contents which he already has in current_cart.

Just update the link

<%= link_to "Checkout", @cart.paypal_url(products_url) %>

To

<%= link_to "Checkout", current_cart.paypal_url(products_url) %>
Kirti Thorat
  • 52,578
  • 9
  • 101
  • 108
  • Hi, thank you for your reply, but I'm not sure exactly how to go about that, brain is in 'derp' mode today. Also, i've followed everything on http://stackoverflow.com/questions/1850905/passing-object-into-a-rails-partial-render thinking it would help, but to no avail. Thanks again, Ben. – Ben Murphy Apr 08 '14 at 20:44
  • Hi again, thanks for your speedy reply. I tried something similar before (though i did not know to drop the @ inside of the partial). However this still leads to "undefined method `paypal_url' for nil:NilClass", so i've no idea what the problem is! – Ben Murphy Apr 08 '14 at 21:11
  • ` i did not know to drop the @ inside of the partial` : Just replace `@cart` with `cart` in `_display_cart.html.erb` file. – Kirti Thorat Apr 08 '14 at 21:13
  • Aye, I've done that, i mean the post i had previously read did not state that, however I've done it as you stated, but to no avail. Apologies if i was unclear. _navigation.html.erb now says: `<%= render :partial => '/display_cart', :locals => {:cart => @cart} %>` and _display_cart.html.erb says `<%= link_to "Checkout", cart.paypal_url(products_url) %>` – Ben Murphy Apr 08 '14 at 21:15
  • Where are you setting the `@cart` variable? Share the controller code which renders the Main Page(within which you are rendering the partial _display_cart.html.erb). – Kirti Thorat Apr 08 '14 at 21:18
  • The partial is rendered within all pages, as it's part of the navigation bar itself. Application.html.erb renders the _navigation partial; within the _navigation.html.erb is the partial which adds the cart to the navigation bar as a drop down. I had assumed rendering the partial set the @cart variable. Due to this I'm unsure what to add into a controller?(I assume it will needed to be within all controllers?) I had thought the partial rendering would set the variable. Apologies for my lack of knowledge on this. – Ben Murphy Apr 08 '14 at 21:55
  • Yes, now you are on target. You will need to set @cart at application level. Please accept the answer when you get a chance. – Kirti Thorat Apr 08 '14 at 21:58
  • Hi again, I've attempted to set it in the application controller, following some research on various websites, I've set `before_filter :load_carts` and `def load_carts @carts = Cart.all end` But still nothing! What am i doing wrong?! :/ – Ben Murphy Apr 08 '14 at 23:22
  • Spot on! You're a hero, been wracking my brains for hours on this. Thank you so much. – Ben Murphy Apr 08 '14 at 23:52