this object:
"permission_category": [{
"id": 2,
"name": "user",
"permissions": {
"id": 2,
"name": "userCreate"
}
},
{
"id": 2,
"name": "user",
"permissions": {
"id": 3,
"name": "userUpdate"
}
}
]
can i convert it to this?
"permission_category": [{
"id": 2,
"name": "user",
"permissions": [
{
"id": 2,
"name": "userCreate"
},
{
"id": 3,
"name": "userUpdate"
},
]
}
]
Do I have such a chance? Because if I return this with foreach it will print the same category name more than once. Is it possible to show both userCreate and userUpdate permissions belonging to the user category under one category? The object looks like this to me. I have created a relationship between 4 tables in Laravel. I will share their code with you too. Please tell me if what I need to do is change the code between relationships. Please tell me if what I need to do is to edit the array in the output with php array functions. I don't know anything about this, I need some help. Sorry for prolonging the topic. I'm sure there's a right and easy way to do this. Since I don't know, I had to ask. I would like to express my thanks and regards to those who have helped in advance.
Laravel Relationship:
UsersController.php
public function add() {
$data = array();
$user = AdminUsers::where('id', $this->uid())->first();
if($user->hasAdministrator()->first())
$data['permission_category'] = PermissionCategory::with('permissions')->get();
else
$data['permission_category'] = PermissionsResource::collection($user->permissions()->with('category')->get());
return $data;
die();
return view('admin.users.add', $data);
}
PermissionsResource.php
return [
"id" => $this->category[0]->id,
"name" => $this->category[0]->name,
"permissions" => [
"id" => $this->id,
"name" => $this->name
],
];
AdminUsers.php (Model)
public function permissions() {
return $this->belongsToMany(Permissions::class, 'admin_perms');
}
Permissions.php (Model)
public function category() {
return $this->belongsToMany(PermissionCategory::class, 'permissions', 'id');
}
admin_users table:
-id
-username
permission_category table:
-id
-name
permissions table:
-id
-permission_category_id
-name
admin_perms table:
-id
-admin_users_id foreign key
-permissions_id foreign key
do
$adminPermsWithCategory = AdminPerms::with('permission.category')
->where('admin_users_id', $user->id);->get();
return new AdminPermsResource($adminPermsWithCategory);
and in AdminPermsResource:
$data = [];
foreach ($this->resource as $item) {
if(!array_key_exists($item->permission->category->name, $data)){
$data[$item->permission->category->name] = [
"category_id" => $cat->id,
"category_name" => $cat->name,
];
}
$data[$item->permission->category->name]['permissions'][$item->permission->id] = new PermissionsResource($item->permission);
}
return $data;
and in PermissionsResource:
return [
"permission_id" => $this->id,
"permission_name" => $this->name,
];
maybe this help. I am writing without trying, sorry for the answer before.
Related
On laravel docs I found a guide to use a Model as Pivot on many-tomany relation.
https://laravel.com/docs/5.6/eloquent-relationships#many-to-many
(scroll to section "Defining Custom Intermediate Table Models")
So I'm trying it and it is working.
Models
Channel => title
Company => id
Tables
channels => id, title
companies => id
company_channel => channel_id, company_id, SCORE
Pivot model
class CompanyChannel extends Pivot
{
protected $table = 'company_channels';
public $timestamps = false;
protected $fillable = [
'score', <<<<<========= PIVOT FIELD I NEED
];
The problem is the serialized json doesn't include pivot-model fields.
public function channels() { return $this->belongsToMany('\App\Channel')->using('App\CompanyChannel'); }
{
"id": 1,
"channels": [
{
"id": 1,
"pivot": {
"empresa_id": 1,
"channel_id": 1
<<<<<====== NOT INCLUDE PIVOT FIELD
}
}
]
}
When I add withPivot to Company model relation, then it returns the field in JSON.
public function channels() { return $this->belongsToMany('\App\Channel')->using('App\CompanyChannel')->withPivot('score'); }
{
"id": 1,
"channels": [
{
"id": 1,
"pivot": {
"empresa_id": 1,
"channel_id": 1,
"score": 50 <<<<<====== NOW IT WORKS
}
}
]
}
So, is there any way to return pivot-model fields automatically? Or do I have to set all fields manually on withPivot?
I want to get the sum of prices from contract table and sum of transactions together connected to user id. And how can i use where in this.
Table Contracts:
[
{
"id": 1,
"user_id":97,
"price":"100"
},
{
"id": 2,
"user_id":97,
"price":"200"
},
{
"id": 3,
"user_id":97,
"price":"300"
}
]
Table Transactions:
[
{
"id": 1,
"user_id":97,
"sum":"100"
},
{
"id": 2,
"user_id":97,
"sum":"200"
},
{
"id": 3,
"user_id":97,
"sum":"300"
}
]
My query:
$query = User::where([
['contracts_sum', '<', 'transactions_sum'],
])
->join('contracts', 'contracts.user_id', '=','users.id')
->join('transactions', 'users.id', '=','transactions.user_id')
->groupBy(['users.id'])
->select(
'users.id', 'users.name',
DB::raw('SUM(contracts.price) AS contracts_sum'),
DB::raw('SUM(transactions.sum) AS transactions_sum'),
)
->get();
But this variant returns sum multiplied to count of transactions table rows like this:
[
{
"id":97,
"name":"JOHN",
"contracts_sum":"1800",
"transactions_sum":"1800"
}
]
But i would like to get the data in this kind of form:
[
{
"id":97,
"name":"JOHN",
"contracts_sum":"600",
"transactions_sum":"600"
}
]
My advice would be to make use of laravel's relation feature, as it would make it a lot easier.
class User
{
public function transactions()
{
return $this->hasMany(Transaction::class, 'user_id', 'id');
}
public function contracts()
{
return $this->hasMany(Contract::class, 'user_id', 'id');
}
}
Then, in your controller, you could do the following:
$user = User::where('id', 97)
->withSum('contracts', 'price')
->withSum('transactions', 'sum')
->get();
return [
'id' => $user->id,
'name' => $user->name,
'contracts_sum' => $user->transactions_sum_sum,
'transactions_sum' => $user->contracts_sum_price
];
Not only does this look a lot cleaner, the query will be more efficient as well. More information on the aggregate functions can be found in the laravel documentation.
I got a table encuesta that has a relationship encuesta_pregunta, the table encuesta_pregunta has a relationship to encuesta_respuesta, it return this
"id": 4,
//...table info...
"encuesta_preguntas": [
{
"id": 10,
"encuesta_id": 4,
"pregunta_id": 5,
//...table info....
"encuesta_respuestas": [
//this relationship can be empty
]
},
{
"id": 11,
"encuesta_id": 4,
"pregunta_id": 3,
//...table info....
"encuesta_respuestas": [
]
},
{
"id": 12,
"encuesta_id": 4,
"pregunta_id": 2,
//...table info....
"encuesta_respuestas": [
]
}
]
}
is there a way to checheck from without looping throught each encuesta_preguntas to know if encuesta_respuesta is empty?
o get the response above like this
$encuesta = Encuesta::with(['encuestaPreguntas' => function($preguntas) {
$preguntas->with(['encuestaRespuestas' => function($respuestas) {
$respuestas->where('user_id','=',auth()->id());
}]);
}])->where('fecha_inicio','<=',date('Y-m-d'))
->where('fecha_fin','>',date('Y-m-d'))
->first();
First. You can do it with Laravel accesors
public function getHasEncuestasAttribute()
{
return $this->encuesta_pregunta != [];
}
When you do $model->has_encuestas it will become true if the relationship isn't empty.
Second. Using relationship method has or doesntHave. If you want to get all the encuesta that have empty relationship you can call Encuesta::doesntHave('encuesta_pregunta') or the opposite that dont have empty relationship Encuesta::has('encuesta_pregunta').
i have googled for solution to my problem but nun helped me.
here i have three tables items, feeds and images. each item has one feed and one or more images.
i have 3 functions. one is to return records from items table the second one receives feeds_id (foreign key in items table) then return records from feeds table. the third function is to return all images related to items_id.
those functions are :
* To get all items in database:
function get_items(){
return $query = Database::getInstance('db')
->table('items')
->columns(
'id',
'items.rowid',
'items.feed_id as feed_id',
'title' )
->findAll();
}
* To get feed data from feeds table :
function get_feeds($id){
return $query = Database::getInstance('db')
->table('feeds')
->eq('id',$id)
->findAll();
}
* To get image data from images table :
function get_images($id){
return $query = Database::getInstance('db')
->table('images')
->columns('items_id','src as image_url',
'title as image_title',
'alt')
->eq('items_id',$id)
->findAll();
}
Then i have the following code to call those function and display the result in jsonformat:
$response['items'] = array();
$response['feeds'] = array();
$response['images'] = array();
foreach ($items = get_items() as $item) {
$response['items'][] = array(
'id' => (int)$item['rowid'],
'feed_id' => (int)$item['feed_id'],
'title' => $item['title'],
);
foreach ($feeds = get_feeds((int)$item['feed_id']) as $feed) {
$response['feeds'][] = array(
'title' => $feed['title'],
'logo_url' => $feed['logo_url'],
'site_url' => $feed['site_url'],
);
}
foreach ($images = get_images($item['id']) as $image) {
$response['images'][] = array(
'id' => $image['items_id'],
'url' => $image['image_url'],
'thumb' => $_SERVER['SERVER_NAME'] . /myServer/images/thumbs/'. 'thumb_'.basename($image['image_url']),
'title' => $image['image_title'],
'alt' => $image['alt']
);
}
}
echo json_encode($response, JSON_PRETTY_PRINT);
so, my expectation is to get json output like:
"items": [
{
"id": ,
"feed_id":
"title":
"feeds": [
{
"title": ,
"logo_url": ,
"site_url": "
}
]
"images": [
{
"id": ,
"url": ",
"thumb":
"title": "",
"alt": ""
},
{
....
}
]
}]
i mean each item array should include nested arrays of its related data coming from get_feeds and get_images functions.
instead of that, i get response like :
//here i select two items from my db
"items": [
{ //first_item
"id": ,
"feed_id":
"title":
},
{ //second_item
"id": ,
"feed_id":
"title":
}
],
"feeds": [
{ // feed data for first item
"title": ,
"logo_url": ,
"site_url": "
},
{ // feed data for second item
"title": ,
"logo_url": ,
"site_url": "
}
],
"images": [
{ // image data for first item
"id": ,
"url": ",
"thumb":
"title": "",
"alt": ""
},
{ // other images data
....
}
]
}]
as you see i am getting output without keeping relation between items, feeds and images, all of them are shown independently.
my queries are fine but i am suspecting error in my foreach statements.
i could fix this issue by joining those tree tables in one query, but i don't want to do that because i need to do validation and other operations to output comes from each table.
i appreciate your help
i found the solution. it is very easy :)
it is just like:
$response['items'][] = array(
'id' => (int)$item['rowid'],
'feed_id' => (int)$item['feed_id'],
'title' => $item['title'],
'feeds' => array(
)
'images' => array(
)
);
I have the next document in MongoDB:
Contest document:
{
"_id": ObjectId("502aa915f50138d76d11112f7"),
"contestname": "Contest1",
"description": "java programming contest",
"numteams": NumberInt(2),
"teams": [
{
"teamname": "superstars",
"userid1": "50247314f501384b011019bc",
"userid2": "50293cf9f50138446411001c",
"userid3": "50293cdff501384464110018"
},
{
"teamname": "faculty",
"userid1": "50247314f501384b0110100c",
"userid2": "50293cf9f50138446410001b",
"userid3": "50293cdff501384464000019"
}
],
"term": "Fall 2012"
}
Imagine that I have more than this document where users can register. I want to find all the contest that a user has registered. I have something like this so far:
$id = "50247314f501384b011019bc";
$user = array('userid1' => $id, 'userid2' => $id, 'userid3' => $id );
$team = array('teams' => $user);
$result =$this->collection->find($team);
return $result;
Could somebody help me with that?
Thank you.
------Solved------
$team = array('$or' => array(array('teams.userid1' => $id),
array('teams.userid2' => $id),
array('teams.userid3' => $id)
));
$result =$this->collection->find($team);
Your data structure is awkward to query because you have an array of embedded documents. With a slight change to the data you could make this easier to work with.
I've put the user IDs into an array:
{
"contestname": "Contest1",
"description": "java programming contest",
"numteams": 2,
"teams": [
{
"teamname": "superstars",
"members": [
"50247314f501384b011019bc",
"50293cf9f50138446411001c",
"50293cdff501384464110018"
]
},
{
"teamname": "faculty",
"members": [
"50247314f501384b0110100c",
"50293cf9f50138446410001b",
"50293cdff501384464000019"
]
}
],
"term": "Fall 2012"
}
You could then do the PHP equivalent find() for:
db.contest.find(
{'teams.members':'50247314f501384b011019bc'},
{'contestname':1, 'description':1}
)
Which would return the matching contests this user had entered:
{
"_id" : ObjectId("502c108dcbfbffa8b2ead5d2"),
"contestname" : "Contest1",
"description" : "java programming contest"
}
{
"_id" : ObjectId("502c10a1cbfbffa8b2ead5d4"),
"contestname" : "Contest3",
"description" : "Grovy programming contest"
}