is it possible to use a relational field of the own model i've worked?
For example
_name = 'x.x'
x_ids = fields.Many2many('x.x')
I need to show the records I've created of the same model in relation field, any suggestions?
That is entirely possible, and you can use relational ways exactly the same way then you would do it with an another model.
Related
Im trying to learn GraphQL with Laravel & Lighthouse and have a question Im hoping someone can help me with. I have the following five database tables which are also defined in my Laravel models:
users
books
user_books
book_series
book_copies
I'd like to create a GraphQL endpoint that allows me to get back an array of users and the books they own, where I can pull data from multiple tables into one subfield called "books" like so:
query {
users {
name
books {
title
issue_number
condition
user_notes
}
}
}
To accomplish this in SQL is easy using joins like this:
$users = User::all();
foreach ($users as $user) {
$user['books'] = DB::select('SELECT
book_series.title,
book.issue_number
book_copies.condition,
user_books.notes as user_notes
FROM user_books
JOIN book_copies ON user_books.book_copy_id = book_copies.id
JOIN books ON book_copies.book_id = books.id
JOIN book_series ON books.series_id = book_series.id
WHERE user_books.user_id = ?',[$user['id']])->get();
}
How would I model this in my GraphQL schema file when the object type for "books" is a mashup of properties from four other object types (Book, UserBook, BookCopy, and BookSeries)?
Edit: I was able to get all the data I need by doing a query that looks like this:
users {
name
userBooks {
user_notes
bookCopy {
condition
book {
issue_number
series {
title
}
}
}
}
}
However, as you can see, the data is separated into multiple child objects and is not as ideal as getting it all in one flat "books" object. If anyone knows how I might accomplish getting all the data back in one flat object, Id love to know.
I also noticed that the field names for the relationships need to match up exactly with my controller method names within each model, which are camelCase as per Laravel naming conventions. Except for my other fields are matching the database column names which are lower_underscore. This is a slight nitpick.
Ok, after you edited your question, I will write the answer here, to answer your new questions.
However, as you can see, the data is separated into multiple child objects and is not as ideal as getting it all in one flat "books" object. If anyone knows how I might accomplish getting all the data back in one flat object, Id love to know.
The thing is, that this kind of fetching data is a central idea of GraphQL. You have some types, and these types may have some relations to each other. So you are able to fetch any relations of object, in any depth, even circular.
Lighthouse gives you out of the box support to eloquent relations with batch loading, avoiding the N+1 performance problem.
You also have to keep in mind - every field (literally, EVERY field) in your GraphQL definition is resolved on server. So there is a resolve function for each of the fields. So you are free to write your own resolver for particular fields.
You actually can define a type in your GraphQL, that fits your initial expectation. Then you can define a root Query field e.g. fetchUsers, and create you custom field resolver. You can read in the docs, how it works and how to implement this: https://lighthouse-php.com/5.2/the-basics/fields.html#hello-world
In this field resolver you are able to make your own data fetching, even without using any Laravel/Eloquent API. One thing you have to take care of - return a correct data type with the same structure as your return type in GraphQL for this field.
So to sum up - you have the option to do this. But in my opinion, you have to write more own code, cover it with tests on you own, which turns out in more work for you. I think it is simpler to use build-in directives, like #find, #paginate, #all in combination with relations-directives, which all covered with tests, and don't care about implementation.
I also noticed that the field names for the relationships need to match up exactly with my controller method names within each model, which are camelCase as per Laravel naming conventions.
You probably means methods within Model class, not controller.
Lighthouse provides a #rename directive, which you can use to define different name in GraphQL for your attributes. For the relation directives you can pass an relation parameter, which will be used to fetch the data. so for your example you can use something like this:
type User {
#...
user_books: [Book!]! #hasMany(relation: "userBooks")
}
But in our project we decided to use snak_case also for relations, to keep GraphQL clean with consistent naming convention and less effort
How to add multiple tables in one model without creating new model.
Is this standard practice to use same in laravel-lumen.
Or should I create 50 models to work on 50 tables.
You can't use multiple table in one model. Each model is written for a specific table.
https://laravel.com/docs/5.7/eloquent#introduction
Laravel uses Eloquent Object Relational Mapper. So each model is like a class representation having methods to do query underneath.
You have to create 50 models if you have 50 tables, or at-least for the tables you are using in your application. TO save time, go for plugins like this which would generate eloquent models based on your database structure. Also check another plugin if it helps.
It's not possible.
Each table should have their own model. But it isn't necessary all the times to make a model for each table. Investing some time on making model will help a lot in future work.
I currently do have a vehicles table that holds "Cars".
Now I want to allow the system to have Bikes, Cars and Trucks.
They have some fields in common (manufacturer_id, mileage, ... ) but they also have specific fields (Bike: cylinder_capacity, seats; Car: doors, ...)
I have tried using all columns in vehicles table and then use the models to handle the differences, But i had problems setting the fillable fields for the child models...
Then I read about polymorphic relations and it seems the right way to go.
So, my questions are: Which approach is the best? What is the best way to implement it?
Thanks!
Create additional tables:
vehicles_types to store types, like cars, bikes etc.
vehicles_attributes to store specific type attributes related via vehicle_type_id with fields vehicle_type_id, name, value.
I extend other models occasionally, and it works as expected. The migrations need to be set up separately, but the class logic (attributes and methods) will work in the normal OOP way. If you're familiar with this, just do what you're doing!
In my database schema, I have multiple tables that hold generic data for objects, for instance I have a user table and a user_data, post table and post_data, and so. these *_data tables all hold a foreign key to the object and a pair of key-value. now in my laravel models I would like to have a single data models for these tables (rather than a model for every single one) and represent the has_many relation in a dynamic way where somehow I can define the table name according to the parent model. I think the parent model would have something like:
return $this->hasMany('data');
but I don't know how to express the inverse relation nor how to tell laravel which *_data table to use. so my question is, is it possible? and if so, how?
You have two options.
Either create a model for each data_* table and use the relation as stated with $this->hasMany('data'); and $this->belongsTo('User'); in the data table and the user table.
Or you can use Polymorphic relations, I personally prefer the polymorphic relations solution, more neat.
I am designing a project in asp.net mvc3, i have designed my database in sql server, add i am using ado.net.
This is my controller action
public ViewResult ProductFormulationIndex()
{
return View(db.ProductFormulation.ToList());
}
means i want to display all fields of ProductFormulation table.
this is my table:-
and this is my productCategory Table
in my ProductFormulationIndex.cshtml i want to display Code of ProductCategory Table, not only id. So what should i do in controller or in Model for it ?
you may suggest tutorial related to it.
Thanks in advance.
You need a view model which is specifically designed for the view.
When defining your view models you shouldn't be thinking in terms of tables. SQL tables have absolutely no meaning in a view. Think in terms of what information you need to show and define your view models accordingly.
Therefore, You can define a view model like:
public class ProductInformation
{
...
public string CategoryCode {get; set;}
...
}
Or public Category ProductCategory.
You can use AutoMapper to convert between your real models and the view model you have defined.
You can find a good tutorial at http://weblogs.asp.net/shijuvarghese/archive/2010/02/01/view-model-pattern-and-automapper-in-asp-net-mvc-applications.aspx
Although I may not answer your question you are touching on some interesting points.
I subscribe to the school of thought that says one should not query an object model but rather make use of a denormalized lightweght query layer.
You will pobably quickly run into the lazy-loading and projection issue: i.e. you do not always require the related data and you do not always require all the fields. A query layer takes care of this quite nicely since using a denormalized model means that when you do your query you do not need to do N-number of joins to get the related data. You will still at some point need to gather up the data but you actual view queries will be order fo magnitude faster.
Also, getting all the data (by joining) for your denormalized model is a once-off affair as opposed to doing it each and every time you display the relevant data on the front-end.
Hope that makes sense :)