Laravel: with method on a collection - laravel

I have a Laravel App. In this I have the models Tasks and Comments. Its a manyToOne relation. One task can have many comments.
I want to give back all tasks with the attached comments.
Im able to do it with one task. Example
$Task = Task::find($id)->with("comments")->get();
Its returning me the Task with the field "comments". In this field is an array of all comments.
{
"id": 1,
"type": "Aufgabe",
"comments": [
{
"id": 1
},
{
"id": 2
},
{
"id": 3
}
]
}
But now I want to get ALL tasks with the comments attached. Im getting all tasks with:
Task::all()
But my problem now, its a collection of tasks and this collection dont have the comments() or with() command.
"message": "Method Illuminate\\Database\\Eloquent\\Collection::with does not exist.",
I could iterate through all the tasks, call with() on each of them and then build the answer by my own, but I think there needs to be a way to do it Laraval thats quick and a one-liner

Related

Is there a way to write an Expression in Power Automate to retrieve item from SurveyMonkey?

There is no dynamic content you can get from the SurveyMonkey trigger in Power Automate except for the Analyze URL, Created Date, and Link. Is it possible I could retrieve the data with an expression so I could add fields to SharePoint or send emails based on answers to questions?
For instance, here is some JSON data for a county multiple choice field, that I would like to know the county so I can have the email sent to the correct person:
{
"id": "753498214",
"answers": [
{
"choice_id": "4963767255",
"simple_text": "Williamson"
}
],
"family": "single_choice",
"subtype": "menu",
"heading": "County where the problem is occurring:"
}
And basically, a way to create dynamic fields from the content so it would be more usable?
I am a novice so your answer will have to assume I know nothing!
Thanks for considering the question.
Overall, anything I have tried is unsuccessful!
I was able to get an answer on Microsoft Power Users support.
Put this data in compose action:
{
"id": "753498214",
"answers": [
{
"choice_id": "4963767255",
"simple_text": "Williamson"
}
],
"family": "single_choice",
"subtype": "menu",
"heading": "County where the problem is occurring:"
}
Then these expressions in additional compose actions:
To get choice_id:
outputs('Compose')?['answers']?[0]?['choice_id']
To get simple_text:
outputs('Compose')?['answers']?[0]?['simple_text']
Reference link here where I retrieved the answer is here.
https://powerusers.microsoft.com/t5/General-Power-Automate/How-to-write-an-expression-to-retrieve-answer/m-p/1960784#M114215

Laravel Test intermittently failing due to 1 second difference

I have the following type of test for most models across my application:
* #test
*/
public function an_authorised_user_can_delete_a_contact()
{
$contact = Contact::factory()->create();
$this->assertDatabaseHas('contacts', $contact->getAttributes());
$response = $this->actingAs($this->user_delete)
->delete('/contacts/'.$contact->id);
$this->assertSoftDeleted('contacts', $contact->getAttributes());
$response->assertRedirect('contacts');
}
This works well most of the time, but every now and then will fail due to the timestamps being slightly out.
Failed asserting that any soft deleted row in the table [contacts] matches the attributes {"first_name":"Katherine","last_name":"Will","title":"Jewelry Model OR Mold Makers","telephone":"+15127653255","mobile":"+19366193055","email":"lucy.lind#example.net","vendor_id":1,"updated_at":"2022-04-04 18:09:50","created_at":"2022-04-04 18:09:50","id":1}.
Found: [
{
"id": 1,
"first_name": "Katherine",
"last_name": "Will",
"title": "Jewelry Model OR Mold Makers",
"telephone": "+15127653255",
"mobile": "+19366193055",
"email": "lucy.lind#example.net",
"vendor_id": 1,
"created_at": "2022-04-04 18:09:50",
"updated_at": "2022-04-04 18:09:51",
"deleted_at": "2022-04-04 18:09:51"
}
]
The difference is in updated_at - "2022-04-04 18:09:50" vs "2022-04-04 18:09:51".
Is there a better way to structure the test to make it more robust?
1st solution:
Use Carbon::setTestNow('2022-04-04 18:09:50') , this will make timestamps not change.
2nd solution (recommended):
Since you wrote the test to check if an authorized user can delete a contact I would not check all attributes as you did but instead would assert the model itself, which is recommended on laravel documentation, here's the link:
$this->assertSoftDeleted($contact);
or only check with the id
$this->assertSoftDeleted('contacts', [
'id' => $contact->id
]);
You can also check out this answer on laracast forum maybe it well help you more.
After deleting the contact record, you should fetch a fresh instance of the model. Try this:
...
$deletedContact = $contact->fresh();
$this->assertSoftDeleted('contacts', $deletedContact->getAttributes());
$response->assertRedirect('contacts');
I would also remove $this->assertDatabaseHas('contacts', $contract->getAttributes()); to make the test run a bit faster. When writing tests you should be testing your own code, not the Laravel framework.
In your factory try to override the "created_at" attribute an hour ago.
public function definition()
{
return [
'created_at'=> $this->faker->dateTimeBetween('-1 hour' );,
'updated_at'=> \Carbon\Carbon::now()->timestamp;
];
}

Insert Document with reference to Existing Document in another Collection

I'm using Java Spring and MongoDB.
I have two collections: customer and order.
I have a reference from the order to the customer collection.
I have an already existing customer.
I want to create a new order with reference to the existing customer.
My POST body request looks like this:
{
"type": "SaaS",
"units": 5,
"price": 30000,
"customer":{
"$ref": "customer",
"$id": {
"oid": "6230853866f97257c050d330"
}
}
}
However, the java serialization process can't resolve the customer subdocument. I understand that I need to apply some logic here but I can't find nor understand how to do it. Basically in mongosh syntax it look similar to this:
db.order.updateOne({_id: ObjectId("623070ab3207ac1de9f8351c")}, {$set: {customer: new DBRef('customer', new ObjectId("6230824c942afc6dee673f3b"))}})

Using GraphQL structures to build complex database queries

I would like to specify inner constraints in a GraphQL query that would limit the results of the outermost query as part of a query / predicate builder I'm working on. I'm not sure if this is considered to be within GraphQL's capabilities but it makes sense to me as something that people would want to do.
For example, I might want to show a list of blog posts that were recently commented on like this:
{
posts{
title
date
comments(since: $earliestDate){
body
date
author {
name
}
}
}
}
The normal behaviour of this would be to bring back all blog posts and only comments that met the criteria.
{
"posts": [
{
"title": "Post 1",
"date": "2017-07-31"
"comments": [
]
},
{
"title": "Post 2",
"date": "2017-06-10",
"comments": [
{
"body": "Comment text",
"date": "2017-08-09",
"author": {
"name": "Michael"
}
}
]
}
]
}
But I want my query to prevent the retrieval of "Post 1" because it has no comments in the last month, but I'm not sure that's something GraphQL will make easy to do.
Is there functionality within GraphQL to support returning this result?
{
"posts": [
{
"title": "Post 2",
"date": "2017-06-10",
"comments": [
{
"body": "Comment text",
"date": "2017-08-09",
"author": {
"name": "Michael"
}
}
]
}
]
}
TL;DR - In general, you want the behavior of a field to only be defined by:
The arguments passed to that field
The identity of the object that is being queried
The global context of the query (eg, the identity of the user executing the query)
I think that the behavior you're after is not really ideal for GraphQL. At least as I've seen, GraphQL tends to treat fields as relatively independent from each other (even though they're nested).
For example, you would not expect arguments passed to a child field to change the behavior of its parent. And similarly, I think you would not expect the presence or absence of a child field to change the behavior of its parent.
The best way to accomplish the behavior you're after would be to add an argument to the posts field, indicating that only posts with comments should be returned:
{
posts(withCommentsOnly: true) {
title
date
comments(since: $earliestDate) {
body
date
author {
name
}
}
}
}
To understand the reasons why, just think about these kinds of scenarios:
{
authors {
id
posts {
comments { body }
}
}
}
If this query has the behavior you describe, for each author, you would only get the posts which also have comments. But then imagine that you re-query one of those authors later:
{
node(id: "author_id") {
... on Author {
posts { title }
}
}
}
Now would you get a different set of posts? That kind of behavior would make it very difficult for people to query your GraphQL schema using standard GraphQL clients, because client-side caching mechanisms would probably not be able to correctly update their caches.

Rethinkdb: Including a subdocument for nested doc

I am performing an operation, and it works, but I want to know if there is a better or more efficient way to do what I want.
I have an object in my db that looks like this:
{
"id": "testId",
"name": "testName",
"products": [
{
"name": "product1"
"info": "sampleInfo",
"templateIds": [
"asdf-1",
"asdf-2"
]
},
{
"name": "product2"
"info": "sampleInfo",
"templateIds": [
"asdf-1",
"asdf-2"
]
}
]
}
As you can see, each "product" in the "products" array has a sub-array of templateIds. These match templates stored in another table. What I want to do is create a query that merges those templates onto each product object before I send it all back.
Currently I am doing this with sub-merges:
r.table('suites').get('testId').merge(function(suite){
return {
products: suite('products').merge(function(product){
return {
templates: r.expr(product('templateIds')).map(function(id) {
return r.table('templates').get(id)
})
}
})
}
})
My question is: is there a more efficient way to do this? Or is there a completely different way of thinking I should employ to do this?
Thanks guys!
That looks right to me. The only thing I can think of is that r.table('templates').get_all(r.args(product('templateIds'))) is shorter than product('templateIds').map(function(id){ return t.table('templates').get(id);}) and might well be faster.
EDIT: If you have a small number of templates, another thing that would make this run faster would be to do the substitution in the client instead and cache the retrieved templates by ID. RethinkDB will have to do a separate read for each template ID, even if it sees the same one over and over again, because it doesn't know enough to know whether or not caching those values is safe.

Resources