Iloverails
Iloverails

Reputation: 1

Execute view before controller?

Just started learning rails. I'm building my first e-shop.

I have my page products/index which list my products. This is the view (in Slim) :

- @products.each do |product|
 br 
 .ul class='list-group'
  li class="list-group-item row"
  .textlist class="col-lg-10 col-md-10 col-sm-10 col-xs-9"
    .element_products
      h4 <b>Category :</b>  #{product.category}
    .element_products
      h4 <b>Description :</b> #{product.content}
    .element_products
      h4 <b>Price :</b> #{product.price} euros
  button class='btn btn-primary btn-right' class="col-lg-1 col-md-1 col-sm-2 col-xs-3" 
    p <b>Add to Cart</b>
    = link_to 'Add', shopping_cart_path(:product_id => product.id), :method => 'POST'
    i class="fa fa-cart-plus"

This code uses this gem for the shopping cart. I'm trying to get a list of products in products/index, with a button to add the items to the cart.

The important part here is that I'm doing a #each on my Product table (line #1). I have a controller for products, as follow :

  class ProductsController < ApplicationController
     def index
        @user = User.find(session[:user_id])
        @products = Product.all
        @product = Product.new
      end
     [...]
  end

And this is my controller for the shopping cart :

class ShoppingCartsController < ApplicationController
   before_filter :extract_shopping_cart

 def create
    @product_cart = Product.find(@product_id)
    @shopping_cart.add(@product_cart, @product_cart.price)
    redirect_to shopping_cart_path
 end

 def show
 end

  private
  def extract_shopping_cart
     shopping_cart_id = session[:shopping_cart_id]
     @shopping_cart = session[:shopping_cart_id] ?     
     ShoppingCart.find(shopping_cart_id) : ShoppingCart.create
     session[:shopping_cart_id] = @shopping_cart.id
   end
 end

The problem :

In my view I use .each to show all products from the Product table. To create a new product, I need to define @product_cart (the product that I want to add to my cart) in the controller ShoppingCartsController, line#5.

For now I defined it like this :

        @product_cart = Product.find(@product_id)

@product_id should increase every time my .each loop in the view is executed, so I can get Product.find(1), then Product.find(2), then Product.find(3)... But I can't do that with the @products.each loop because this one is used in the view to display all the products. And the view is executed AFTER the controllers.

Is there any way to increment @product_id with the .each loop in my views, THEN get @product_id used by the controller in Products#create ?

Upvotes: 0

Views: 53

Answers (1)

Sravan
Sravan

Reputation: 18647

You are sending the product Id to the create method of the cart through this link.

 = link_to 'Add', shopping_cart_path(:product_id => product.id), :method => 'POST'
i class="fa fa-cart-plus"

Here you are sending product_id., Which you can use in controller through params.

Your controller should be changed to,

class ShoppingCartsController < ApplicationController
   before_filter :extract_shopping_cart

 def create
    @product_cart = Product.find(params[:product_id])
    @shopping_cart.add(@product_cart, @product_cart.price)
    redirect_to shopping_cart_path
 end

 def show
 end

  private
  def extract_shopping_cart
     shopping_cart_id = session[:shopping_cart_id]
     @shopping_cart = session[:shopping_cart_id] ?     
     ShoppingCart.find(shopping_cart_id) : ShoppingCart.create
     session[:shopping_cart_id] = @shopping_cart.id
   end
 end

If you take params[:product_id] you will get the id's of the product selected to add to cart, with which you can create.

Upvotes: 2

Related Questions