getting column not found when trying to reference a type in relationship table - laravel

how would i get the type name of my referenced table in my get
Here is my database example:
mainTable
id | typeid
1 | 1
2 | 1
3 | 2
And here is my second table
typesTable
id | type
1 | test
2 | test2
3 | test3
My relationship in my main table model is defined as :
public function type()
{
return $this->belongsTo('App\Models\typesTable', 'typeID');
}
And here is how im pulling the data:
try {
$data = Main::with('type')
->groupBy('typeID')
->get(array(
DB::raw('type as date') <---getting type column does not exist-->,
DB::raw('COUNT(*) as "views"')
));
return Respond::Ok('Success', $data);
} catch (\Throwable $th) {
return Respond::Bad('Failed', $th);
}
my problem is i cannot get the type name in my get array and am getting an error..
if i remove that line i get the following data back:
message: "Success"
data:
0: {views: 2, type: null}
1: {views: 1, type: null}
2: {views: 1, type: null}
meta: null
Please help

Related

facing difficulty on implementing "groupBy" method in laravel

I am trying to fetch data using groupBy method in laravel, but it's returning all data. what I am trying to get is
lets there are 2 tables
Table 1 : variants
id variant
1 color
2 size
Table 2: product_variants
color variant_id
red 1
yellow 1
red 1
sm 2
xl 2
lg 2
Now I want to fetch data so it returns as follow:
variant_table: {
id:1,
variant: color,
variants: {
variant_id: 1,
color:red
},
{
variant_id: 1,
color:yellow
}
},
{
id:2,
variant: size,
variants: {
variant_id: 2,
color:sm
},
{
variant_id: 2,
color:lg
},
{
variant_id: 2,
color:xl
}
}
But I am getting all variants instead of distincts grouped by variant_table id, My code:
$productVariants = ProductVariant::with('productVariants')
->whereHas('productVariants',function ($q) {
$q->groupBy('variant_id');
})
->get();
let suppose the model of product_variants table is ProductVariant
let suppose the model of variants table is Variant
let suppose the in model ProductVariant the relation function name is variant()
$product_variants = ProductVariant::with('variant')->groupBy('variant_id')->get();
try this $product_variants = ProductVariant::with('variant')->get()->groupBy('variant_id');
if it does not work than config\database.php --> "mysql" array
Set 'strict' => false

laravel API fetch data from table base on the unique id

I want to create an API that display and fetch data from table(users) and another table(fruits) together base on the unique id (fruit_id) common in both table.
table->users
+----------+------------+----------+--------------+
| Id | Fruit_id | Name | Gender |
+----------+------------+----------+--------------+
| 1 | B456 | Mary | Female |
| 2 | O174 | James | Male |
table->fruits
+----------+------------+----------+--------------+
| Id | Fruit_id | Name | Quantity |
+----------+------------+----------+--------------+
| 1 | B456 | Banana | 22 |
| 2 | O174 | Orange | 34 |
I created an API in laravel where fetch all data in the users table from my controller
class UserApiController extends Controller
{
public function index()
{
return Users::all();
}
}
API display result
[
{
id: 1,
fruit_id: B456,
name: Mary,
gender: Female,
},
{
id: 2,
fruit_id: O174,
name: James,
gender: Male,
}
]
I want the API to display like the below based on the unique id (fruit_id) selection that is common between both tables how will I write the code in my controller to display the desired result.
Desired result
[
{
id: 1,
fruit_id: B456,
name: Mary,
gender: Female,
fruits: [
id: 1,
fruit_id: B456,
name: Banana,
Quantity: 22,
]
},
{
id: 2,
fruit_id: O174,
name: James,
gender: Male,
fruits: [
id: 2,
fruit_id: B456,
name: Orange,
Quantity: 34,
]
}
]
You should create a relationship inside Model\User. Then, you can use with() or load().
Example:
Users::all()->load('fruits');
https://laravel.com/docs/8.x/eloquent-relationships#one-to-many
you need to make one-to-many relationship between tables
table->users
Id - Name - Gender
table->fruits
Id - user_id - Name - Quantity
class User extends Model{
public function fruits(){
return $this->hasMany(Fruit::class,'user_id');
}
}
class Fruit extends Model{
public function user(){
return $this->belongsTo(User::class,'user_id');
}
}
User::with('fruits')->get();

How can I create a relationship between `json` column and a `int` (id) column in Hasura + Postgres?

I have 2 tables users and post
Table users has columns id and post, column contains an array of the form [1, 2, 3, 4, 5] - where 1, 2, 3, 4, 5 is id in table post
In the table posts the following columns id and text
Table users:
https://i.stack.imgur.com/ywdS7.png
Table posts:
https://i.stack.imgur.com/IBdpb.png
in hasura made an array relation
https://i.stack.imgur.com/311sd.png
Next I made the following request
{
users_test {
postz {
id
}
}
}
I would like to receive such data in response:
postz: [
   {
     text: 'qwe'
   },
   {
     text: 'sdf'
   }
]
But with such a request, I get a trace. error:
{
"errors": [
{
"extensions": {
"internal": {
"statement": "SELECT coalesce(json_agg(\"root\" ), '[]' ) AS \"root\" FROM (SELECT row_to_json((SELECT \"_5_e\" FROM (SELECT \"_4_root.ar.root.postz\".\"postz\" AS \"postz\" ) AS \"_5_e\" ) ) AS \"root\" FROM (SELECT * FROM \"public\".\"users_test\" WHERE ('true') ) AS \"_0_root.base\" LEFT OUTER JOIN LATERAL (SELECT coalesce(json_agg(\"postz\" ), '[]' ) AS \"postz\" FROM (SELECT row_to_json((SELECT \"_2_e\" FROM (SELECT \"_1_root.ar.root.postz.base\".\"id\" AS \"id\" ) AS \"_2_e\" ) ) AS \"postz\" FROM (SELECT * FROM \"public\".\"posts\" WHERE ((\"_0_root.base\".\"post\") = (\"id\")) ) AS \"_1_root.ar.root.postz.base\" ) AS \"_3_root.ar.root.postz\" ) AS \"_4_root.ar.root.postz\" ON ('true') ) AS \"_6_root\" ",
"prepared": true,
"error": {
"exec_status": "FatalError",
"hint": "No operator matches the given name and argument type(s). You might need to add explicit type casts.",
"message": "operator does not exist: json = integer",
"status_code": "42883",
"description": null
},
"arguments": [
"(Oid 114,Just (\"{\\\"x-hasura-role\\\":\\\"admin\\\"}\",Binary))"
]
},
"path": "$",
"code": "unexpected"
},
"message": "postgres query error"
}
]
}
What am I doing wrong and how can I fix it?
A few suggestions:
There are some typos in your query, as far as I can tell. Try:
{
users {
id
posts {
text
}
}
}
You don't need the post column on the users table. You just need a user_id column on the posts table, and a foreign key constraint from the posts table to the users table using the user_id and id columns of the tables respectively. Check out the docs here:
https://docs.hasura.io/1.0/graphql/manual/schema/relationships/create.html#step-3-create-an-array-relationship
https://docs.hasura.io/1.0/graphql/manual/schema/relationships/database-modelling/one-to-many.html
If you have to have the post array column for some reason, you can use computed fields to create a "relationship" between a json array and another table’s id.
https://docs.hasura.io/1.0/graphql/manual/schema/computed-fields.html#table-computed-fields
Your function would:
Take in the json array column
Extract the id's
Return select * from table where id in id's
Example:
https://jsonb-relationships-hasura.herokuapp.com/console/api-explorer
Computed field definition at: https://jsonb-relationships-hasura.herokuapp.com/console/data/schema/public/tables/authors/modify
Run these queries:
# Get list of articles for each author
query {
authors {
id
name
articles
}
}
# Get actual articles for each author
query {
authors {
id
name
owned_articles {
id
title
}
}
}

How to define values specific to a connection of two nodes in GraphQL?

I have two types in my schema:
type Resident = { type Visitor = {
id id
name name
} }
In my database:
Residents and Visitors Tables:
+--------+-------+ +--------+---------+
| res_id | name | | vis_id | name |
+--------+-------+ +--------+---------+
| 1 | Alice | | 1 | Charlie |
| 2 | Bob | +--------+---------+
+--------+-------+
And then a table that shows which visitor belongs to which resident:
+--------+--------+--------------+
| res_id | vis_id | relationship |
+--------+--------+--------------+
| 1 | 1 | fam/fri |
| 2 | 1 | contractor |
+--------+--------+--------------+
Each visitor could either be a "fam/fri" or a "contractor" to a resident. So Charlie is Alice's visitor as her family or friend. However, Charlie is also a visitor to Bob, but instead as a contractor.
Question: How do I structure my schema so that when I query Alice, Charlie returns as a fam/fri, and when I query Bob, Charlie is returned as a contractor? I imagine this:
{
Resident(id: 1) { "Resident" {
name "Alice"
Visitor { "Visitor" {
id ===> "1"
name "Charlie"
relationship "fam/fri"
} }
} }
}
and also:
{
Resident(id: 2) { "Resident" {
name "Bob"
Visitor { "Visitor" {
id ===> "1"
name "Charlie"
relationship "contractor"
} }
} }
}
Something like:
type Query {
resident(id: Int): Resident
}
type Resident {
id: Int!
name: String!
visitors: [Visitor!]!
}
type Vistor {
id: Int!
name: String!
relationship: VisitorRelationship!
}
enum VisitorRelationship {
CONTRACTOR
FAMILY_OR_FRIEND
}
Note that by convention field names should be camelCase and type names should be in PascalCase. If the data returned from your data source (whether that's a database, API, or whatever) is not in the same shape as what you want to return from your GraphQL service, then you should transform the data before returning it inside your resolver, for example:
const relationshipMap = {
'fam/fri': 'FAMILY_OR_FRIEND',
'contractor': 'CONTRACTOR',
}
const resolvers = {
Query: {
resident: (root, args) => {
const resident = await Resident.findById(args.id)
// assuming resident has a property named joinTable that's
// an array and each relationship has a property named visitor
return {
...resident,
visitors: resident.joinTable.map(relationship => {
return {
...joinTable.visitor,
relationship: relationshipMap[joinTable.relationship],
}
})
}
},
},
}
You can also map enums to custom values this way.

How to groupBy and count the pivot table in laravel?

I have three tables,
User cities user_cities
id name title id name user_id city_id
1 aaa designer 1 cityA 2 1
2 bbb developer 2 cityB 2 2
3 ccc designer 3 cityC 1 2
1 1
2 3
3 2
After joining and querying the database my result is,
data: {
0: {
id: 1
name: aaa,
title: designer,
cities :[
0: {
id: 1,
name: cityA
}
1: {
id: 2,
name: cityB
}
2: {
id: 3,
name: cityC
}
]
},
1: {
id: 2
name: bbb,
title: developer,
cities :[
0: {
id: 1,
name: cityA
}
1: {
id: 2,
name: cityB
}
]
}
1: {
id: 3
name: ccc,
title: designer,
cities :[
0: {
id: 2,
name: cityB
}
]
}
}
Everything is fine until here. But i want to groupBy by cities and take count.
If i filter by title=designer the filtered data will display and i want to make group by cities and take count of it.
So my final result will be,
cityA = 1 counts
cityC = 2 counts
Help me to solve the problem.
You might use the withCount to eager load the relationship counts.
I assume you already have the cities relationship defined in the User.php model:
class User
{
public function cities()
{
return $this->belongsToMany(City::class);
}
}
Then:
$users = User::withCount('cities')->get();
I think the results are gonna be:
data: {
0: {
id: 1
name: aaa,
title: designer,
cities_count: 3
},
1: {
id: 2
name: bbb,
title: developer,
cities_count: 2
}
1: {
id: 3
name: ccc,
title: designer,
cities_count: 1
}
}
An alternative could be using lazy eager loading:
$users = User::all()->loadCount('cities');

Resources