laravel one to many(select all rows from second table) - php

i want to select all services rows from servs table
_____ i have two tables users with model(User) ..... and servs with model(servs) ... . uwant to select all rows from servs when it auth User
How can i do that ???
public function postserv(){
$serv = User::find(Auth::user()->id)->servs;
$serv = $serv->first();
return $serv->serv_id;
}

I'm not sure of the model name, but it should be something like Serv::all()

Your question is very vague and it's hard to determine what's going on in your project but I'll give it a shot.
If you want to select all rows of a model use the following:
Services::all()
Whilst that is what you're explicitly asking for, your question seems to pertain to a relationship where you select all services for a user.
User::find(Auth::user()->id)->servs()->get();
This will return all services that are joined to the authorised user, on the note of naming conventions you should make your relations more readable.
Also note that you must have your relationships set up in your Eloquent models else the above code would fail.
In future try to add a little more detail for your questions, there is more information about relationships in the Eloquent ORM on the Laravel website.

ModelName::all();
Returns all rows from a model/table.

Related

Laravel select from DB where in Collection - Laravel Nova

I have a DB, "views," with many, many entries. I also have a "Courses" table, which these views are one-many related to. In Laravel Nova, I can get a metric of all views over time for a course with some code like this:
public function calculate(Request $request)
{
return $this->countByDays($request, view::where('viewable_id', $request->resourceId));
}
In this case, viewable_id is the id of the course, and $request->resourceId gives the ID of the course to sort by. Pretty simple.
However, now things get a little difficult. I have another model called Teachers. Each Teacher can have many courses, also in a one-many relationship. How do I get a metric of views over time for all the courses that teacher teaches?
I assumed the simplest way to do this would be to create a Laravel Collection with all courses the Teacher teaches (not exactly efficient), and then select all views in the database where viewable_id matches one of the courses in that list. Of course, by posting this, I couldn't figure out how to do that.
Of course, once this is figured out, I'd love to do the same thing for Categories (though that should function in a very identical manner to Teachers, so I don't need to ask that question).
How do I get a metric of views over time for all the courses that teacher teaches?
This should be the "countByDays" of views where the viewable_id is in the list of course ids that the teacher teaches.
An SQL query statement to achieve that is given below:
select * from "views"
where "viewable_id" in (select "id" from "courses" where "teacher_id" = ?)
The Eloquent query should be similar to:
$this->countByDays($request,
view::whereIn(
'viewable_id',
Course::with('teacher')
->select('id')
->where('teacher_id', $request->resourceId)
)
);

Php: use data from a join table with mvc

Heya I am novice web dev or actually I am still in education.
I got this situation Where I have 3 tables lets say : Students, Groups and a join table Student_group.
I put my data from Students in the student model and from groups I put its data in the Group Model so I can use it my application. But I store a date in the Student_group table because I need to know when a student changed from a group.
So my question is in which model do I put this date? Do i need to make a new model for the combined tables or do I need to add another attribute to the student model?
Thanks in advance ;D
That depends. Will the student be in many groups, or one?
If one (one to one relationship), you can decide where to put it. The column could be in either the Student table, or the Student_group. In this case, though, it may be advisable to flatten the data and simply add group columns in your Student table. You decide that as well - if it seems unnecessary to have a join for a one to one relationship (usually it is, not always), then flatten it. In either case, the data should stay in its respective model. That said, you should use the Student model if you handle it in the Student table.
If many (one to many relationship), I'd advise putting it in the Student_group table and leaving it in that model as well.
All in all, the model should be a direct reflection of the data it's representing. You could make some methods inside your Student model to make it easier to get the date, for example. However, I'd personally handle that date inside of the proper model, Student_group. As mentioned, the model should be a direct representation of the data. Again, though, there's nothing wrong with making things a bit easier by creating some methods that help out the developer.

laravel Eloquent join and Object-relationship mapping

Ok so i'm kind of newish to eloquent and laravel (not frameworks tho) but i hit a wall here.
I need to perform some queries with conditions on different tables, so the eager load (::with()) is useless as it creates multiples queries.
Fine, let use the join. But in that case, it seems that Laravel/Eloquent just drops the concept of Object-relationship and just return a flat row.
By exemple:
if i set something like
$allInvoicesQuery = Invoice::join('contacts', 'contacts.id', '=', 'invoices.contact_id')->get();
and then looping such as
foreach ($allInvoicesQuery as $oneInvoice) {
... working with fields
}
There is no more concept of $oneInvoice->invoiceFieldName and $oneInvoice->contact->contactFieldName
I have to get the contacts fields directly by $oneInvoice->contactFieldName
On top of that the same named columns will be overwrited (such as id or created_at).
So my questions are:
Am i right assuming there is no solution to this and i must define manually the field in a select to avoid the same name overwritting like
Invoice::select('invoices.created_at as invoice.create, contacts.created_at as contact_create)
In case of multiple joins, it makes the all query building process long and complex. But mainly, it just ruins all the Model relationship work that a framework should brings no?
Is there any more Model relationship oriented solution to work with laravel or within the Eloquent ORM?
Instead of performing this join, you can use Eloquent's relationships in order to achieve this.
In your Invoice model it would be:
public function contact(){
return $this->belongsTo('\App\Contact');
}
And then of course inside of your Contact model:
public function invoices(){
return $this->hasMany('\App\Invoice');
}
If you want to make sure all queries always have these active, then you'd want the following in your models:
protected $with = ['Invoice']
protected $with = ['Contact'];
Finally, with our relationships well defined, we can do the following:
$invoices = Invoice::all();
And then you can do:
foreach($invoices as $invoice)[
$invoice->contact->name;
$invoice->contact->phone;
//etc
}
Which is what I believe you are looking for.
Furthermore, you can find all this and much more in The Eloquent ORM Guide on Laravel's site.
Maybe a bit old, but I've been in the same situation before.
At least in Laravel 5.2 (and up, presumably), the Eloquent relationships that you have defined should still exist. The objects that are returned should be Invoice objects in your case, you could check by dd($allInvoiceQuery); and see what the objects are in the collection. If they are Invoice objects (and you haven't done ->toArray() or something), you can treat them as such.
To force only having the properties in those objects that are related to the Invoice object you can select them with a wildcard: $allInvoicesQuery = Invoice::select('invoices.*')->join('contacts', 'contacts.id', '=', 'invoices.contact_id')->get();, assuming your corresponding table is called invoices.
Hope this helps.

Laravel, do I need multiple database tables for votes on different models

I have a Question model which has a one to many relationship with an Answer model.
Now I want to add upvote/downvote funcionality to both of these models, do I need to create two tables like VotesQuestions and VotesAnswers or can I somehow manage with one? If so, how?
You can use a polymorphic relationship. This is built into Laravel. Documentation is here. The code shown here is for Laravel 4, but the functionality is the same for Laravel 5.
Create a votes table, and make sure it has at least two specific fields: votable_id and votable_type. In a database migration, you would use the statement $table->morphs('votable');, and it will create the two fields. You can have as many other fields as you like, but to make sure the relationship works, those two fields are required.
Next, setup the Vote model with the votable relationship. The name of this relationship should match the base name of the fields you created:
class Vote extends Eloquent {
public function votable() {
return $this->morphTo();
}
}
With this setup, you can now associate votes to any model you want. Go ahead and add the votes relationship to the Question and Answer models:
class Question extends Eloquent {
public function votes() {
return $this->morphMany('Vote', 'votable');
}
}
class Answer extends Eloquent {
public function votes() {
return $this->morphMany('Vote', 'votable');
}
}
You can now access the votes for any question/answer through the relationship:
$q = Question::first();
$qVotes = $q->votes; // Collection of votes for the question.
$a = Answer::first();
$aVotes = $a->votes; // Collection of votes for the answer.
You can also get the related question/answer model through the vote, if you ever need to:
$v = Vote::first();
$vRelated = $v->votable; // Will automatically be a Question or Answer object, depending on what the vote was for.
I would do an table for the question and when you want to up/downvote the question there should be a count column for both, otherwise you want to log it that an user can only vote for it once, so you need another table for user_id, question_id and type (up/down).
ofc you can handle it with one table, but that is really worth because you save many things that are not necessary.
you can create a table with an internal id, 1,2,3,4 and 1 is always the question or 0 and 2-xx (1-xxx) are always the answers. so you can handle it with one table
You could create a generic Votes model/table which has a field called "model" and "model_id" and then use reflection to get the correct object.

How should I structure the Eloquent ORM models for multiple intermediate tables in Laravel?

I can't find anywhere the information on how you have several intermediate tables with your Eloquent ORM models. The problem I'm facing is that I have a table for my users, permissions and roles. These are the 4 tables:
Permissions:
id
name
Permission_roles:
id
name
Permission_role_mappings:
id
permission_id
permission_role_id
Permission_role_user_mappings:
id
permission_role_id
user_id
(Well, I also have a users table but the layout of it doesn't matter since the foreign key is in permission_role_user_mapping.)
So the problem is that I want to be able to get the data from the permissions table when calling from the User model. I have some trouble grasping the workflow with Eloquent ORM altogether so if I'm missing something basic which is crucial then please point it out.
According to the documentation it seems that I don't need to create models for the intermediate tables. So how would I specify the relationship from the User class? Could I do something similar to this?
class User extends Eloquent {
public function permission_role()
{
return $this->has_many_and_belongs_to('Permission_Role', 'permission_role_user_mappings');
}
public function permission()
{
return $this->has_many_and_belongs_to('Permission_Role', 'permission_role_user_mappings')->has_many_and_belongs_to('Permission','permission_role_mappings');
}
}
This doesn't seem to be working, this is the error:
User::find(1)->first()->permission()->first();
...
Method [permission] is not defined on the Query class.
I also want to be able to get data by starting from Permission_Role and Permission. I'd prefer that the answer would help me specifying all the models required.
Eloquent relationships are accessed as an object property instead of a function.
User::find(1)->first()->permission;
You can wrap that above statement in the dd function to get a look at it.
This guide on Eloquent Relationships should be helpful
Edit for question in comments about selecting all permissions in the role:
$roles = array();
$permission_roles = User::find(1)->permission_roles()->get();
foreach ($permission_roles as $pr) {
if (! in_array($pr->permissions)) {
$roles[] = $pr->permissions;
}
}
This will get you what you want. However, this will end up doing a lot of queries. It's best to make use of Eager Loading here.

Categories