use first() instead of get()
Update record using where clause
How would I update the records in the db using this where clause.
$option = Options::where('products_id', '=', $id)->get();
$option->product_id = $product->id;
$option->size = Input::get('size');
$option->colour = Input::get('colour');
$option->stock = Input::get('stock');
$option->save();
Has the save() or update() method's through back an error.
first() works just fine, I can't use Options::find($id); as the id isn't the same as what's been passed through.
You cannot change the id on an eloquent save() method.
Basically I have an options table like so:
id products_id size colour stock
1 17 6 Black 2
2 17 10 Yellow 3
So in the CMS when I update a line from these select menu's - http://cl.ly/image/0u1A3c2G0W2J i want it to update the right one, so i need to pass the id as well as the products_id as the picture show the edit form with these dropdowns on come from the product table id of 17 in this case but then get the id from the options table to be able to update that row based on the edits in the form, how can this be done?
With the option ID you should'nt need the products_id to get the right row to update. You product id is base on what ? The size ?
Products Table - http://cl.ly/image/1C3H0z2w3Z2B Product Options Table - http://cl.ly/image/3C2C1q36181r
Is how the two tables are set, but if i edit a product within the cms it get the products table id in this instance is '17' but the id in the options isn't 17 but the products_id in the products_options table is.
You should use a relationship method for this.
Products.php model
public function options()
{
return $this->hasMany('Options');
}
Options Model
public function products()
{
return $this->belongsTo('Products');
}
Already setup but not sure how to link the two.
In your option table, you should use the singular for the product key ('product_id' instead of 'products_id')
Then from your product class :
$product = Product::find($id);
// Return the option collection corresponding to the product
$option = $product->options()->get();
Ah right and use get or first? as I'm not doing a foreach. @RemiC
And trying to update something returns
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'product_options.products_id' in 'where clause' (SQL: select * from `product_options` where `product_options`.`products_id` = 17 limit 1)
So should I be using local and foreign keys here too? If so how?
You have to check the structure of your pivot table (product_options) and use the corresponding keys.
I'm getting
Call to undefined method Illuminate\Database\Eloquent\Collection::save()
Using this:
$product = Products::find($id);
$option = $product->options()->get();
$option->product_id = $product->id;
$option->size = Input::get('size');
$option->colour = Input::get('colour');
$option->stock = Input::get('stock');
$option->save();
Or it doesn't update the right row
If you see this short video i made you will see it doesn't update http://cl.ly/1A1B1o000u3M
You can't just call save() on a collection object. I'm not sure to understand what your goal is. Do you want to update all the options for a given product with the same values ?
No the options all have different values and when using the update form it needs to update the correct row with the new values.
I've also had to use ->first() instead of get()
So, my question is, how do you know which row to edit ?
That's just it I don't, that's kinda what i'm asking for help on.
Ok, all you have to pass the option 'id' in your POST request, then query the Option table from there.
Not sure i follow, can you explain more or show code to what you mean.
@lstables In fact, you have a unique identifier (id) for each options. You must use this field to fetch and update your option because it's the only unique identifier in your database schema.
You can user Eloquent relations to fetch product option relations to build your form but not for update.
You problem is probably the way you building your form right now. You must provide someway to identify properly your options in your form.
How would I do that within my form though
@lstables I think the best way is to have one form row per options. You should add the option first, with some value, and add the row to your form. Every form options row should have her proper ID i mean.
But my edit form is like this all with form model binding with one {{ Form::open() }}
How you add options right now?
Form:
{{ Form::model($product, ['method' => 'PUT', 'route' => ['admin.products.update', $product->id], 'class' => 'form-horizontal', 'files' => true]) }}
<div class="form-group">
<div class="col-sm-2">Product Name</div>
<div class="col-lg-3">
<input type="text" name="name" class="form-control" value="{{ $product->name }}">
</div>
</div>
<div class="form-group">
<div class="col-sm-2">Category</div>
<div class="col-lg-3">
<?php $selected_category = ($product->slug ?: null) ?>
{{ Form::select('category_id', $category, $selected_category, ['class' => 'form-control'])}}
</div>
</div>
<div class="form-group">
<div class="col-sm-2">SEO Title</div>
<div class="col-lg-3">
<input type="text" name="seo_title" class="form-control" value="{{ $product->seo_title }}">
</div>
</div>
<div class="form-group">
<div class="col-sm-2">SEO Description</div>
<div class="col-lg-3">
<input type="text" name="seo_description" class="form-control" value="{{ $product->seo_description }}">
</div>
</div>
<div class="form-group">
<div class="col-sm-2">Content</div>
<div class="col-lg-10">
<textarea name="content">{{ $product->content }}</textarea>
</div>
</div>
<div class="form-group">
<div class="col-sm-2">Image</div>
<div class="col-lg-3">
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#myModal" data-target=".bs-example-modal-lg">
Current Images
</button>
</div>
<div class="col-lg-3">
{{ Form::file('image') }}
<span class="help-block">Uploading a new image will overwrite previous</span>
</div>
<div class="col-lg-3">
{{ Form::file('image2') }}
</div>
<div class="col-lg-2">
{{ Form::file('image3') }}
</div>
</div>
<div class="form-group">
<div class="col-sm-2">Price</div>
<div class="col-lg-3">
<div class="input-group">
<span class="input-group-addon">&pound;</span>
<input type="text" name="price" class="form-control" value="{{ money_format("%i", $product->price) }}">
</div>
</div>
</div>
<div class="form-group">
@foreach($options as $option)
<div class="col-sm-2">Size</div>
<div class="col-lg-3">
<?php $selected_size = $option->size; ?>
{{ Form::select('size', $sizes, $selected_size, ['class' => 'form-control'])}}
</div>
<div class="col-sm-1">Colour</div>
<div class="col-lg-2">
<?php $selected_colour = $option->colour; ?>
{{ Form::select('colour', $colours, $selected_colour, ['class' => 'form-control'])}}
</div>
<div class="col-sm-1">Stock</div>
<div class="col-lg-2">
<input type="text" name="stock" class="form-control" value="{{ $option->stock }}">
</div>
@endforeach
</div>
<div class="form-group">
<div class="col-sm-2">Status</div>
<div class="col-lg-3">
<?php $options = array('Inactive', 'Active'); ?>
{{ Form::select('status', $options, Input::old('status'), array('class' => 'form-control')) }}
</div>
</div>
<div class="form-group">
<div class="col-lg-3">
<button class="btn btn-success">Update</button>
</div>
</div>
{{ Form::close() }}
Methods
public function edit($id)
{
$product = Products::find($id);
//$option = Options::where('product_id','=', $id)->get();
$prod_id = $product->id;
$options = Options::where('product_id', $prod_id)->get();
$category = Categories::lists('name','slug');
$sizes = [null, 'Please Select'] + Sizes::lists('name','name');
$colours = Options::lists('colour', 'colour') + Colours::lists('name', 'name');
return View::make('products.edit', compact('product','category','sizes','colours','options'));
}
public function update($id)
{
$product = Products::find($id);
$product->name = Input::get('name');
$product->seo_title = Input::get('seo_title');
$product->seo_description = Input::get('seo_description');
$product->content = Input::get('content');
$product->price = Input::get('price');
if (Input::hasFile('image')){
$file = Input::file('image');
$destinationPath = public_path(). '/uploads/product-images/original/';
// If the uploads fail due to file system, you can try doing public_path().'/uploads'
$name = str_random(60).'.'.$file->getClientOriginalExtension();
//$filename = $file->getClientOriginalName();
//$extension =$file->getClientOriginalExtension();
Input::file('image')->move($destinationPath, $name);
$product->image = $name;
$product->orig_image = $name;
}
if (Input::hasFile('image2')){
$file = Input::file('image2');
$destinationPath = public_path(). '/uploads/product-images/original/';
$name = str_random(60).'.'.$file->getClientOriginalExtension();
Input::file('image2')->move($destinationPath, $name);
$product->image2 = $name;
$product->orig_image2 = $name;
}
if (Input::hasFile('image3')){
$file = Input::file('image3');
$destinationPath = public_path(). '/uploads/product-images/original/';
$name = str_random(60).'.'.$file->getClientOriginalExtension();
$file->move($destinationPath, $name);
$product->image3 = $name;
$product->orig_image3 = $name;
}
$product->status = Input::get('status');
$product->slug = strtolower(Input::get('category_id'));
$product->price = Input::get('price');
$product->update();
// This is the part to update the options table
if (Input::get('size') ?: null) {
$option = $product->options()->first();
$option->product_id = $product->id;
$option->size = Input::get('size');
$option->colour = Input::get('colour');
$option->stock = Input::get('stock');
$option->save();
}
return Redirect::to('admin/products')->with('flash_success','Product successfully updated.');
}
Any idea's based on my post? @maximebeaudoin
I could put an hidden input in but then how would i get the value of each select and then update it in the db with the option id i just set in a hidden field.
Please or to participate in this conversation.