JMSserializer deserialize related Doctrine Entity - php

I have json like this:
"relatedCollection": [
{
id:1,
name: "something",
country: {
id:1
}
},
{
id:2,
name: "something 2",
country: {
id:1
}
}
]
Two related items that have a common country that exists in database. If I deserialize with JMSserializer, and it creates a two different instances of COUNTRY entity.
When you apply merge with doctrine, set properly country to "something", but not to "something 2". So the result after save is:
"relatedCollection": [
{
id:1,
name: "something",
country: {
id:1
}
},
{
id:2,
name: "something 2",
country: null
}
]
For Doctrine there are two different entities called Country that are detached. And doctrine attach the first and save it properly but not the second.
This only happens with relations ManyToOne, when you merge a collection with the same related entity id.
If you save country 1 and country 2, there'is no repeated country, so save property.
Any solution?

JMS Serializer just does the object deserialization, it does not handles the doctrine object for you.
You have to do any kind of merge, cascade merge, for example
http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations
You can write a deserialization Listener\Subscriber to do auto-merge for you automatically

Related

How to use whereIn for column array?

I have data from a table structured like so:
table: students
{
id:
name:
classes: [
{
name: "gym"
},
{
name: "science"
},
{
name: "math"
},
{
name: "english"
}
]
}
reference array: science, math
How do I return only records that match the values found in the reference array. For example, if the reference array contains math and science then all records returned from the student table will need to have those values in the classes array name field.
I'm trying to use whereIn, but it does not accept a column (array) and field as the first parameter.
This might help:
Student::select("*")->whereIn('classes', $referencearray)
->get();

MongoDB update not working with existing array [duplicate]

In MongoDB how do you use $set to update a nested value?
For example, consider a collection people with the following document:
{
_id: ObjectId("5a7e395e20a31e44e0e7e284"),
name: "foo",
address: { street: "123", town: "bar" }
}
How do I update the street field embedded in the address document from "123" to "Main Street"?
Using the dot notation:
db.people.update({ }, { $set: { "address.street": "Main Street" } })
In addition to Niels' answer, also do verify the "type" of the nested value. In my case, it was a "string" formed from json. Though this might be unlikely, but do ensure that the value has the right type.

How to use fractal transformer in Laravel?

I try to use the Fractal library from The PHP League in my project
I have model: Object with fields id, name. It has relation prototypes as one to one.
So, model Prototype has relation Fields. Where model Fields contains fields: name, id.
Also there is separated model: ObjectFields that contains values for each object fields. For example:
object_id | value
1 1
In result I need to get output JSON:
objects : {
"id" : 1,
"name" : "Weapon",
"prototype": {
"id" : 1,
"name" : "Prototype Name",
"fields" : {
"field_name" : ObjectFields.value
}
}
}
Look please on
"fields" : {
"field_name" : ObjectFields.value
}
so, It would be field name as key and value from model ObjectFields.
Now I do request using query as:
Object::with("prototype.field.name.value");
It returns me nested output object, but I need that last 3 realations will be in one object by key field.name

how to fetch a single value from a reference to another collection?

I have two collections - users and chats. Each chat message has a structure like the following:
_id: ObjectId
from: ObjectId // user _id
to: ObjectId // user _id
message: String
date_created: Date
And each user has:
_id: ObjectId
name: String
username: String
// ... not important stuff
I need to fetch conversations that are only sent to me and the result should be in the following way:
{
data: [
{
"id": conversation_id,
"title": username,
"message": message_excerpt
},...
]
}
My problem is trying to get the username from the reference because I don't want to make 20 fetch queries to get 20 different usernames. I would have added the username when the conversation is first created but I can't because the username can be changed any time. This would create an inconsistency between the username and the conversation title. How should I handle this problem? This is the first time I wished there was a JOIN in Mongo.
Two possibilities:
1: Add the username to chat message documents. Like you said, if the username changes, you need to change the username on all the user's chats.
2: Do an application-level join. You don't need to do 20 queries to get the 20 names. You can first retrieve all the chats, then collect all of the user_id values and do one query. For example:
var results = [
{ "_id" : 0, "from" : 43, "to" : 86, "message" : "sup?" },
{ "_id" : 1, "from" : 99, "to" : 86, "message" : "yo" }
]
var from_users = db.users.find({ "_id" : { "$in" : results.map(function(doc) { return doc.from }) } }).toArray()
Now you can use the from_users to populate the username into results or create your desired document structure. Note that results from the $in are necessarily returned in the order of elements in the array argument to $in - this is commonly expected/desired but it's not the case.

Create a blank array from a model in cakephp

hi,
I have a working model and I want to be able to just create an array from it but with only the key names and just have them empty.
To illustrate, my model Client comes from the clients table, and for example when I do this:
$this->Client->find( 'first' );
I get the following array (json encoded):
{
Client: {
id: "39",
name: "andrux",
phone: "1234567890",
email: "me#andrux.com",
city_id: "2"
},
City: {
id: "2",
city_name: "andruxville"
}
}
As you can see, I set this model to have a relationship with the City model, so I get both Client and City arrays as a result of my find method.
Now I need to get the same array but without values, and I just can't find an answer for this, I have tried some solutions but none have worked the way I want, for example I tried using array_map function and the schema method of the model but that just gives me the column names of the clients table, which I can set to null if I want but what about the City model?
The end result I want is the following:
{
Client: {
id: "",
name: "",
phone: "",
email: "",
city_id: ""
},
City: {
id: "",
city_name: ""
}
}
Anyone knows how to accomplish this? I rather find a way of doing this the cakephp way - if there is one - but any solution that gets me to my desired result will be greatly appreciated.
Thanks guys!
Well, if its ok, you could create a custom function in your model and pass in the result to it, like:
//can be added to your model
function reset_values($array, $replace_with) {
foreach ($array as $key => $arr) {
if(is_array($arr)) $res[$key] = reset_values($arr,$replace_with);
else $res[$key] = $replace_with;
}
return $res;
}
$resetedArr = reset_values($arr, null); //replace values with null
echo "<pre>"; print_r($resetedArr);

Categories