Update mongodb collection with a object via eloquent - php

I would like to save the following object to a field on a mongodb collection via eloquent
"project_settings" : {
"resource" : true,
"zone" : true,
"contractor" : true,
"responsible_person" : false
}
this is my php code:
return ProjectModel::where($project_id)->first()->update($project_data);
dont worry about the model it works fine i need to make a query that updates the project collection
and $project_data =
project_settings:array(4)
resource:true
zone:true
contractor:true
responsible_person:true
Right now i get no error back. It returns successful but nothing is updated in reality. Can someone help?

The issue is probably with your inputs.
The method signature of update looks like below:
public function update(array $attributes = [], array $options = [])
So the attributes you pass in must be an array, not an object.
The where() method also need two inputs like where('column_name', $value).
So try something like below:
ProjectModel::find($project_id)->update([
"project_settings" => [
"resource" => true,
"zone" => true,
"contractor" => true,
"responsible_person" => false
],
]);

Related

How to store multiple records via JSON from a Debugger (Lumen, RESTClient)

I'm using RESTClient to send the http request to the backend:
restclient.net
Currently, my JSON looks like this:
[
{"title":"my blogADD","description":"myblogdescriptionADD","status":1},
{"title":"my blogUPDATEDADD","description":"myblogdescriptionUPDATEDADD","status":1},
{"title":"my blog33","description":"myblogdescription33ADD","status":1}
]
The table in the DB looks like this, its name is "articles":
https://imgur.com/onXEgzg
The function inside the controller responsible to insert the data looks like this:
public function create(Request $request){
$this->validate($request, [
'title' => 'required',
'description' => 'required'
]);
//insert record
$article = Article::create($request->all());
return response()->json($article, 201);
}
So far, when I send the request, the data doesn't get inserted.
The header is set to content-type:application/json
inserting a single record works.
Sending the above array of objects doesn't do anything, it doesn't even throw an error.
I already read somewhere that one might use the id as key to identify each object inside the array. But is that really the problem here?
The ID of the table is already the PK and its set to AUTO_INCREMENT, so at least technically assigning an ID manually shouldnt be necessary, although of course the order of the inserted might differ from the order they arrived inside the inputted array.
So what am I missing?
I am pretty new to Lumen, and I'm just learning to use the model.
The controller code stems from a tutorial video:
https://www.youtube.com/watch?v=6Oxfb_HNY0U
I must admit that I don't really understand what the
$request->all()
inside
$article = Article::create($request->all());
does.
When reading the official laravelDOC, I found this syntax to save records to the DB
https://laravel.com/docs/5.8/eloquent
<?php
namespace App\Http\Controllers;
use App\Flight;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class FlightController extends Controller
{
/**
* Create a new flight instance.
*
* #param Request $request
* #return Response
*/
public function store(Request $request)
{
// Validate the request...
$flight = new Flight;
$flight->name = $request->name;
$flight->save();
}
}
and it differs quite a lot from what I have, so I wonder how my syntax actually worx xD
EDIT:
Here is the debugging result of $request->all()
^ array:3 [
0 => array:3 [
"title" => "my blogADD"
"description" => "myblogdescriptionADD"
"status" => 1
]
1 => array:3 [
"title" => "my blogUPDATEDADD"
"description" => "myblogdescriptionUPDATEDADD"
"status" => 1
]
2 => array:3 [
"title" => "my blog33"
"description" => "myblogdescription33ADD"
"status" => 1
]
]
See The API:
https://laravel.com/api/5.8/Illuminate/Database/Eloquent/Builder.html#method_create
create is only save a new model and return the instance.
https://laravel.com/api/5.8/Illuminate/Database/Query/Builder.html#method_insert
Use insert instead of create
Article::insert($request->all());

CakePHP: Unable to save data to parent entity via belongsTo associated child

Problem description
I'm trying to configure a CakePHP 3.7 API to save associated data in a child-first manner. The entities - for the sake of example, lets call them Users and Persons - and their relationships are as follows:
UsersTable.php
...
$this->belongsTo('Persons', [
'foreignKey' => 'person_id',
'joinType' => 'LEFT',
'className' => 'MyPlugin.Persons',
]);
...
PersonsTable.php
$this->hasOne('Users', [
'foreignKey' => 'person_id',
'className' => 'MyPlugin.Users'
]);
In their respective entities, they each have one another's property visibility set to true. What I'm trying to do is POST to the /users/ route (UsersController.php) and have it also save the Persons object included. The payload is as such:
{
"username": "foo",
"password": "bar",
"persons": {
"dob": "1982-07-03",
}
}
The relevant part of the saving method is below, from UsersController.php:
if ($this->request->is('post') && !empty($this->request->getData())) {
$data = $this->request->getData();
$newEntity = $this->Users->newEntity($data, ['associated' => 'Persons']);
$savedEntity = $this->Users->save($newEntity);
...
The error
This produces the following SQL error.
PDOException: SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column 'person_id' violates not-null constraint
DETAIL: Failing row contains (1, null, foo, bar)
I understand this is because Cake is attempting to save to Users without having a person_id to satisfy the foreign key constraint. It's not possible to reverse this FK relationship in my application domain as we desire leftward one-to-many relationship (User -> 1 Person).
I suspect sending an id in the persons object of the JSON payload will allow this to save correctly. However, for various reasons, this isn't possible at runtime. For example, this is how it's shown in the "Saving Data" CakePHP Book page...
$data = [
'title' => 'First Post',
'user' => [
'id' => 1,
'username' => 'mark'
]
];
...
$article = $articles->newEntity($data, [
'associated' => ['Users']
]);
$articles->save($article);
I know the following would also likely work as suggested by xPfqHZ for a similar issue, as Persons can save to Users, but it feels less suitable as compared to what I'm trying to do and feels as if there is a way via the associations on Users.
if ($this->request->is('post') && !empty($this->request->getData())) {
$data = $this->request->getData();
$newEntity = $this->Users->Persons->newEntity($data, ['associated' => 'Persons']);
$savedEntity = $this->Users->Persons->save($newEntity);
...
Workings
Now I believe this used to be possible in CakePHP 2.X, as stated in this answer by ndm on a similar question where a person is attempting to save the belongsTo associated entity and it's parent hasOne entity in one request via the belongsTo entity.
That's the expected behavior, saveAssociated() is not meant to save only the associated records, it will save the main record as well, so you should use saveAssociated() only, no need to manually set the foreign key, etc, CakePHP will do that automatically.
Controller
public function create() {
if ($this->request->is('post') && !empty($this->request->data)):
$this->CandidatesProblemReport->create();
if ($this->CandidatesProblemReport->saveAssociated($this->request->data)):
// ...
endif;
endif;
}
However, I'm not able to find or use the saveAssociated() method upon the Cake\ORM\Table object which the Users entity inherits from, in the documentation. Calling it produces a method not found error. This method only appears to exist on the Cake\ORM\Association object as detailed in the documentation. Unless I'm missing the obvious, is there a way to use this or is it used internally by BelongsTo() and its sibling methods?
Logging / Dumping entity
Using Cake\Log\Log::error($newEntity); or die(var_dump($newEntity)); shows the Users data of the payload hydrated into an object, but I don't see the Persons object attached (see below).
object(MyPlugin\Model\Entity\User)[299]
public 'username' => string 'foo' (length=3)
public 'password' => string 'bar' (length=3)
public '[new]' => boolean true
public '[accessible]' =>
array (size=5)
'*' => boolean false
'person_id' => boolean true
'username' => boolean true
'password' => boolean true
'person' => boolean true
public '[dirty]' =>
array (size=2)
'username' => boolean true
'password' => boolean true
public '[original]' =>
array (size=0)
empty
public '[virtual]' =>
array (size=0)
empty
public '[hasErrors]' => boolean false
public '[errors]' =>
array (size=0)
empty
public '[invalid]' =>
array (size=0)
empty
public '[repository]' => string 'MyPlugin.Users' (length=17)
Attempting to \Cake\Log\Log::error($savedEntity); shows nothing in the log file.
save() associations arguments
Another solution I considered was using the $options['associated] of save() as shown in the documentation (extract below). With this set to true as below, the error still occurred.
save( Cake\Datasource\EntityInterface $entity , array $options [] )
... associated: If true it will save 1st level associated entities as they are found in the passed $entity whenever the property defined for the association is marked as dirty. If an array, it will be interpreted as the list of associations to be saved. It is possible to provide different options for saving on associated table objects using this key by making the custom options the array value. If false no associated records will be saved. (default: true) ...
UsersController.php:
if ($this->request->is('post') && !empty($this->request->getData())) {
$data = $this->request->getData();
$newEntity = $this->Users->newEntity($data, ['associated' => 'Persons']);
$savedEntity = $this->Users->save($newEntity, ['associated' => true]);
...
Summary
Without going through the PersonsController.php and utilising its hasOne relationship, I'm not having much luck getting my Users and Persons data to save through the UsersController.php.
If I've missed any important information, or you have questions/need more, please ask! I might have missed something obvious, but I'd appreciate any suggestions/solutions possible.
As #ndm identified, the error lay in the posted data. As per the "Saving Data: Saving BelongsTo Associations" page of the documentation:
When saving belongsTo associations, the ORM expects a single nested entity named with the singular, underscored version of the association name.
The posted key persons should have been person. Equally, if the entity were named PersonSnapshots, the relevant key in the payload hydrated into the entities would need to have been person_snapshot.

Yii2: Why kartik\select2 widget not filled then I trying update model?

Im have ActiveRecord model and view for update form of this model. Also I have getter and setter in model class that looks like this
public function setTopvisorGoogleRegion($value)
{
$this->myvalue = $value;
return(true);
}
public function getTopvisorGoogleRegion()
{
return([1 => '123']); //I return this array for show you essence of the problem
}
Following logic in this code $model->topvisorgoogleregion must return [1 => '123']
In view I have next code
<?php echo($form->field($model, topvisorgoogleregion)->textInput());?>
<?php echo $form->field($model, 'topvisorgoogleregion')->widget(Select2::classname(), [
'data' => [1 => '123', 2 => '456'],
'options' => [
'id'=>'projectCtrl',
'placeholder' => 'Select option',
'multiple' => true
],
'pluginOptions' => [
'allowClear' => true,
'tags' => true,
],
]);
?>
When I open form I want to see option 1 => '123' already selected in Select2. Its logically because when already existing record is updating, ActiveRecord get data that already stored in model (in this case using getter) and fill fields in view with this data (In first field that using textInput I see text 'Array' because getter in model returns array). But Select2 is empty when I open update page. Whats going wrong?
If I delete first field (textInput) nothing changes
I find the solution - in getter I need provide ActiveQuery object, not array. I dont know why and how it works, but it works

How to use Doctrine Criteria to filter out array properties?

I'm adding a virtual property within a Symfony entity class. This property shall be computed based on another table data - specifically on a column that is of the Doctrine array type.
class RelatedEntity
{
/* ... */
/**
* #ORM\Column(type="array")
*/
protected $type;
The point is I would like to use Doctrine Criteria for this as it's supposed to be optimized on SQL level. So I did this:
public function getCreated()
{
$criteria = Criteria::create()->where(Criteria::expr()->contains('type', 'create'));
$relatedEntity = $this->getRelatedEntities()->matching($criteria);
if (!$relatedEntity) {
return null;
}
return $relatedEntity->getTimestamp();
}
But I get an empty result set. Even though Doctrine is building a correct SQL statement, which works when I type it manually into the PostgreSQL database.
...WHERE type LIKE '%create%'
What is wrong with this approach and how can it be solved? Right now I did the trick with the ArrayCollection filter method, but it loads all related entities I don't need.
Thank you for any ideas.
EDIT: This is not a duplicate of the mentioned question as I cannot use EntityManager or EntityRepository inside an entity. I need to use Criteria, so the solution proposed in the question doesn't work for me.
Check the results of getRelatedEntities()
Depending on how this collection was created, any one of several things may be happening. In particular, it may be using entity aliases, or may not be returning any which match your Criteria.
Collection populated from an aliased entity (i.e.: via a QueryBuilder join/select).
If getRelatedEntities is populated by Doctrine via QueryBuilder, you've likely aliased the Entities.
EX.: $queryBuilder->addSelect('thing')->leftJoin('root_alias.entity',
'thing')
In such a case, the Criteria must use the alias:
Criteria::expr()->contains('thing.type', 'create')
No matches for Criteria.
Dump your collection before filtering it, this could be a simple case of your query having already filtered out any potential matches.
Test your Criteria
All things considered, without any clue as to the structure of the collection you're trying to filter, we can only assess your criteria. Thus, test your criteria, and check the contents of the collection you are attempting to filter.
$criteria = Criteria::create()->where(Criteria::expr()->contains('type', 'create'));
$collection = new ArrayCollection([
[
'key' => 1,
'type' => 'somethingcreatesomething',
],
[
'key' => 2,
'type' => 'abra',
],
[
'key' => 3,
'type' => 'cadabra',
],
[
'key' => 4,
'type' => 'alacreate',
],
]);
dump($collection->matching($criteria));
Result
Doctrine\Common\Collections\ArrayCollection {#2536
-elements: array:2 [
0 => array:2 [
"key" => 1
"type" => "somethingcreatesomething"
]
3 => array:2 [
"key" => 4
"type" => "alacreate"
]
]
}

MongoDB - PHP Group By Count

I have this code :
$data=$collection1->aggregate(array( '$group'=> array('_id'=>$valoreScelto,'contatore'=>array('$sum'=>1))));
$valoreScelto is a valid field of document MongoDB, that i retry by FORM.
$valoreScelto = trim('$'.$campoSelezionato);
I obtain this error:
Fatal error: Call to a member function aggregate() on string
UPDATE:
The error says: You are trying to access the method "aggregate", in the string (Variable $collection1 have type - string).
You need to check $collection1 (for example var_dump). $collection1 must be Collection (or in mongo extension MongoCollection).
You can get a collection like this:
$yourConnectInDB = new Client(...); // or MongoClient(...);
$db = $yourConnectInDB->selectDatabase('YOUR DB NAME');
$collection1 = $db->selectCollection('YOUR COLLECTION NAME');
Also, in your code you want to use the aggregation like this:
$ops = array( // base array
array(
'$group' => array(
"_id" => $valoreScelto,
"contatore" => array('$sum'=>1),
)
),
// other pipeline
);
$data=$collection1->aggregate($ops);
Read this and this
I tried the above answer as well and it wasn't returning anything. After a lot of trying I figured out that I had missed a keyword without which the above query was not going to work. I am pasting the code below.
$ops = [
[
'$group' => [
"_id" => $valoreScelto,
"contatore" => ['$sum'=>1],
]
]
];
$data=$collection1->aggregate($ops)->toArray();

Categories