LaravelShoppingcartというlibraryがあるそうだが、laravel5.4までしか対応していないらしい。
gloudemans/shoppingcart
という事で、以下のlibraryを入れる。
bumbummen99/LaravelShoppingcart
$ composer require bumbummen99/shoppingcart
$ php artisan vendor:publish –provider=”Gloudemans\Shoppingcart\ShoppingcartServiceProvider” –tag=”config”
config/cart.phpが追加される
config/app.php
// Autoloaded Service Providers Gloudemans\Shoppingcart\ShoppingcartServiceProvider::class, // Class Aliases Gloudemans\Shoppingcart\ShoppingcartServiceProvider::class,
config/cart.php
'tax' => 10, 'format' => [ 'decimals' => 0, 'decimal_point' => '', 'thousand_separator' => ',', ],
### productsテーブル作成
$ php artisan make:model Product -m
2020_11_09_214306_create_products_table.php
public function up() { Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('amount'); $table->text('sizes'); $table->timestamps(); }); }
$ php artisan migrate
mysql> describe products;
+————+—————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+————+—————–+——+—–+———+—————-+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| amount | varchar(255) | NO | | NULL | |
| sizes | text | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+————+—————–+——+—–+———+—————-+
6 rows in set (0.01 sec)
app/Models/Product.php
class Product extends Model { use HasFactory; protected $fillable = ['name','amount','sizes']; protected $casts = [ 'sizes' => 'json' ]; }
### Seeder
$ php artisan make:seeder ProductsTableSeeder
database/seeders/ProductsTableSeeder.php
public function run() { for($i=1;$i<=25; $i++){ $product = new \App\Models\Product(); $product->name = $i.'番目の商品名'; $product->amount = array_rand([500, 1000, 1500]); $product->sizes = array_rand([ ['M'], ['M', 'L'], ['S', 'M', 'L'] ]); $product->save(); } }
$ php artisan db:seed
mysql> select * from products;
+—-+———————-+——–+——-+———————+———————+
| id | name | amount | sizes | created_at | updated_at |
+—-+———————-+——–+——-+———————+———————+
| 1 | 1番目の商品名 | 1 | 1 | 2020-11-09 22:34:45 | 2020-11-09 22:34:45 |
| 2 | 2番目の商品名 | 0 | 0 | 2020-11-09 22:34:45 | 2020-11-09 22:34:45 |
| 3 | 3番目の商品名 | 1 | 2 | 2020-11-09 22:34:45 | 2020-11-09 22:34:45 |
| 4 | 4番目の商品名 | 2 | 1 | 2020-11-09 22:34:45 |
// 省略
+—-+———————-+——–+——-+———————+———————+
25 rows in set (0.00 sec)
### routing
routes/web.php
use App\Http\Controllers\Ajax\ProductController; use App\Http\Controllers\Ajax\CartController; use App\Http\Controllers\ProductController; use App\Http\Controllers\CartController; Route::get('products', [ProductController::class, 'index']); Route::get('carts', [PostController::class, 'index']); Route::resource('ajax/products', ProductController::class)->only(['index']); Route::resource('ajax/carts', CartController::class)->only(['index','store','destroy']);
$ php artisan make:controller ProductController
$ php artisan make:controller CartController
$ php artisan make:controller Ajax\\ProductController –resource
$ php artisan make:controller Ajax\\CartController –resource
### Controller
app/Http/Cotnrollers/Ajax/ProductController.php
public function index() { // return \App\Models\Product::get(); }
$ php artisan serve –host 192.168.33.10 –port 8000
http://192.168.33.10:8000/ajax/products
### viewの作成
resources/views/products/index.blade.php
<!DOCTYPE html> <html lang="en"> <head> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"> <meta charset="UTF-8"> <title>Document</title> </head> <body style="padding-top: 10px"> <div id="app"> <div class="container"> <div class="float-right"> カートの中身: <span class="badge badge-pill badge-pill" v-text="Object.keys(cartItems).lenght"></span> 個 </div> <h1>商品一覧</h1> <div class="row"> <div v-for="(product,index) in products" class="col-sm-4"> <div class="card border-info"> <div class="card-body"> <h5 class="card-title" v-text="product.name"></h5> <p class="card-text"> <label>サイズ:</label> <select class="form-control"> <option v-for="size in product.sizes" :value="size" v-text="size"></option> </select> </p> <p class="card-text"> <label>個数:</label> <input type="number" class="form-control" min="0" value="0"> </p> </div> <div class="card-footer text-right"> <button type="button" class="btn btn-info">カートへ入れる</button> </div> </div> <br> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script> <script> new Vue({ el: '#app', data: { products: [], cartItems: {} }, methods: { getProducts: function(){ var self = this; axios.get('http://192.168.33.10:8000/ajax/products') .then(function(response){ self.products = response.data; }); } }, mounted: function(){ this.getProducts(); } }); </script> </body> </html>
addCart
<select ref="size" class="form-control"> // <input ref="size" type="number" class="form-control" min="0" value="0"> // <button type="button" class="btn btn-info" @click="addCart(index)">カートへ入れる</button> // addCart: function(index){ if(confirm('カートへ追加します。よろしいですか?')){ var self = this; var size = this.$refs.size[index].value; var qty = this.$refs.qty[index].value; var product = this.products[index]; var url = '/ajax/carts'; var params = { size: size; qty: qty, productId: product.id }; axios.post(url, params) .then(function(response){ self.cartItems = response.data; }); } }
app/Http/Cotnrollers/Ajax/CartController.php
public function store(Request $request) { // $product = \App\Models\Product::find($request->product_id); \Cart::add( $product->id, $product->name, $request->qty, $product->amount, ['size' => $request->size] ); return \Cart::content(); }
ん? 上手くいかない。。