I am just learning laravel now. And I have this problem. I have passed 2 request parameters to my controller function. First request parameter holds an object value, but I converted it to a serialized form since the field of my table where it will be saved has a text datatype. The second request parameter holds a overall_total calculated value and it has a float datatype field. My problem is, how would I store it in my database? I have tried to use the create function but it returns an error. Some forums regarding this are not so clear. I just can't figure it out yet. Can somebody help me with this? Here are my codes.
function store
public function store(Request $request){
$serialize_po = serialize($request['purchase_orders']);
$overall_total = $request['overall_total'];
$purchase_orders_save = PurchaseOrder::create(?);
}
How would I save 2 parameters using create? or is there other way I can saved it?
Inside of $request['purchase_orders'] is shown in the image below
Inside of $request['overall_total'] is just a number. E.g. 310
My Database Table Structure is shown below
The create() function in Laravel accepts an associative array, where the array keys are the names of the columns, and the array values are the corresponding values for the columns.
So your store function might look something like this:
public function store(Request $request){
$serialize_po = serialize($request['purchase_orders']);
$overall_total = $request['overall_total'];
$purchase_orders_save = PurchaseOrder::create([
'purchase_orders' => $serialize_po,
'overall_total' => $overall_total
]);
}
One other thing to note is that as a safety precaution, Laravel does not allow the properties of a model to be filled in this fashion out of the box. You will need to list in your model using the $fillable property which keys you will allow to be filled by passing in an associative array. If you don't, you'll likely get a MassAssignmentException.
So in your model, you will likely need to have at least the following:
class PurchaseOrder extends Model
{
protected $fillable = ['purchase_orders', 'overall_total'];
}
There are more options and ways to do this, but that is the basic and typical scenario.
More info on using the create() method and handling mass assignment is available in the documentation: https://laravel.com/docs/5.2/eloquent#mass-assignment
Considering your model name is PurchaseOrder, you first need to create a new instance of it. Then, use the save method.
public function store(Request $request)
{
$purchaseOrder = new PurchaseOrder;
$purchaseOrder->overall_total = $request['overall_total'];
$purchaseOrder->purchase_orders = serialize($request['purchase_orders']);
$purchaseOrder->save();
}
See https://laravel.com/docs/5.2/eloquent#basic-inserts for more info.
Something like this :
DB::table('purchaseOrder')->insert(
['purchase_orders' => $serialize_po,'overall_total' => $overall_total]
);
See doc if you want to explore more.
Related
I know that data can be inserted into the database in
Method 1:
public function store(Request $request)
{
// Validate the request...
$flight = new Flight;
$flight->name = $request->name;
$flight->save();
}
Method 2:
$flight = Flight::create([
'name' => 'London to Paris',
]);
What is the best way to use when inserting 1 value? What is the best way to use when you need to insert, say, 10 values? And are there any other better ways to insert values?
Technically speaking, there isn't much difference, but the main thing about create is that it has mass assignment related issues.
What it means is that, for example if you have a model User which has certain fields including a role field which can be user or admin.
Then if you create a new record using create method like this:
$user = User::create($request->all());
then the member can pass the parameter role in request inputs and change his/her own role and get admin privileges, simple as that! You can prevent this with the property $fillable inside your models, but if it is not taken care of properly it will lead to these kind of issues.
One another point is that, the create method uses the save() itself, if you look at its implementation you can see this:
public function create(array $attributes = [])
{
return tap($this->newModelInstance($attributes), function ($instance) {
$instance->save();
});
}
I have two tables user and post.
in my posts method I want to return users posts with custom fileds.
none of below solutions dose not works
class UserController
{
public function posts(User $user)
{
return $user->only(['username', 'name', 'posts.body' // solution one
return $user->only(['username', 'name', 'posts'=>function($q){
$q->select(['body']
}])// solution two
Does anyone have a work around?
in post only get one column value in one row then used value method
Post::where('user_id')->value('body')
if you want to get multiple value(rows) from single column used pluck method
Post::where('user_id')->pluck('body') //this will get on the array
otherwise used select method
Post::select('body')->where('user_id')->get(); // this will get on collection
Post::select('body')->where('user_id')->get()->toArray(); // this will get on array
I have been trying to insert data using query into two columns of a table but there's something missing that its not sending data in the other column named booking_code.
It is inserting the booking_id into the table but not booking_code.
Here is the controller:
public function store(CreatePaymentRequest $request)
{
$input = $request->all();
$booking_id = $request->booking_id;
$booking_code = Booking::find($booking_id)->booking_code;
$this['booking_code'] = $booking_code;
$payment = $this->paymentRepository->create($input);
Flash::success('Payment saved successfully.');
return redirect(route('admin.payments.index'));
}
Please have a look at the Relevant Documentation Pages
You may also use the create method to save a new model in a single line. The inserted model instance will be returned to you from the method. However, before doing so, you will need to specify either a fillable or guarded attribute on the model, as all Eloquent models protect against mass-assignment by default.
That means that you have to set, in Model, which fields you will allow to be "mass-assigned".
In your case, it will looks something like
class Booking extends Model
(...)
{
protected $fillable = ['booking_code', (...)];
}
(...)
In the code you provided though, I can't see how you build an $input variable so maybe the issue is there? Maybe it's just some typo.
So I came across a weird issue while writing tests in laravel using factories. So this is a test I wrote:
/**
#test
*/
public function document_belongs_to_a_patent()
{
$patent = factory(Patent::class)->create();
$document = factory(Document::class)->create([
'documentable_id' => $patent->id,
'documentable_type' => 'patent'
]);
$this->assertArraySubset($patent->toArray(), $document->documentable->toArray());
}
So this should work, right because both should return the same thing and patent array should be equal or a subset of documentable array. But it was failing when I realised that there is an enum field in Patent model to which I am passing the value 1 but it was converted to the enum equivalent value in the database and when I tried document->documentable->toArray() it came back with the enum value rather than 1 which got me thinking how can make the model factory return the actual enum value and not the index number.
Top of the head I just fetched the patent just after creating it via the factory like so:
$patent = Patent::find($patent->id);
And it works well but it seems inconsistent. Is there a way to refresh models. I know we can refresh relationships of models but is there a way to do for the models themselves?
If you're strictly needing the change for API, you can do something cheeky with mutators like this.
https://laravel.com/docs/5.1/eloquent-serialization
Add this property. It tells Laravel that for special outputs only, it needs to append a non-database property.
protected $appends = ['documentable_type_name'];
Then you need some ways of knowing the language for the enum. You need an array, a #lang definition, etc. Here's a protected property solution that I am quite fond of in simple situations.
protected static $documentable_types = [ 'divorce', 'patent' ];
And then create this mutator on your Documentable model.
public function getDocumentableTypeName()
{
if ($this->documentable_type)
{
return static::$documentable_types[ $this->documentable_type ];
}
return null;
}
This changes your JSON output to look like this:
{
docuemntable_id : 555,
documentable_type : 1,
documentable_type_name : 'patent'
}
You can also hide the document_type field by adding this.
protected $hidden = ['documentable_type'];
And Laravel magic takes care of the rest. Hope that helps.
Laravel has the option to add an $appends array to each model making additional values automatically available as if they are database attributes by adding accessors for each.
This is normally pretty handy, except in this case I need to ONLY get the fields I put into select() because DataTables is expecting only what I send to it.
Example:
Item::select(['image', 'name', 'color']);
Will return appended fields after color in the attributes.
How do I force the exclusion of the appends values when returning results?
Or alternatively, how do I get DataTables to ignore certain attributes?
Not sure which is the least time costly route.
Currently using yajra/laravel-datatables package to send data to the jQuery DataTables AJAX request.
You can call each function in the collection object and then use setHidden method to exclude the unwanted fields like this
$item= Item::select(['image', 'name', 'color'])->get()->each(function($row){
$row->setHidden(['appendedField1', 'appendedField2']);
});
And for the yajra/laravel-datatables you can use something like
$item= Item::select(['image', 'name', 'color']);
return Datatables::of($item)->remove_column('appendedField1');
To solve this I added this method to my Item model:
public static function getAppends()
{
$vars = get_class_vars(__CLASS__);
return $vars['appends'];
}
Then used the following code in the controller:
$items = Item::select(['image', 'name', 'color']);
$DT = Datatables::of($items);
call_user_func_array([$DT, 'removeColumn'], Item::getAppends()); // Has to be called this way with yajra/laravel-datatables-oracle v3.* if passing an array.
return $DT->make(true);