Use find() and with() together in Laravel query - sql

I have 2 tables employees and employee_locations. One employee has many locations. I need to find out one employee record with related latest employee_locations record. I wrote below query.
$employees = Employee::find([1])->with('employees.employee_locations')->latest()->first();
I am getting below error
BadMethodCallException
Method Illuminate\Database\Eloquent\Collection::with does not exist.

Your issue is that the find method retrieves a collection of Eloquent objects, on which the with method can not be used. You must first specify your relations for the Employee objects and then use find.
The below code will retrieve the employee with the ids specified in find method and locations for each employee:
$employees = Employee::with('employees.employee_locations')->find([1])

create a relation in your model. Something like this:
class Employee extends Model
{
protected $table = 'employees';
public function location()
{
return $this->hasMany(EmployeeLocation::class, 'employeed_id');
}
}
class EmployeeLocation extends Model
{
protected $table = 'employee_locations';
}
$employees = Employee::with('location')->first();
or you do
$employees = Employee::with('location')->find(<employeed_id>);

Try This method
$employees = Employee::with('employees')->where('employeesid',$employeesid)-
>get()->find($employeesid);

Related

Bug with my relation HasMany/BelongsTo

I have a model Work with this relation
public function types()
{
return $this->belongsTo('App\Models\Type');
}
And a model Type with this relation
public function works()
{
return $this->hasMany('App\Models\Work');
}
I try to access in my view show view to type but I've a lot of errors
Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name
I try this : $work->types()->name for get data.
In my DB, my table 'Works' have a foreignkey 'type_id'.
I would like to get the 'type' of the post. There can be only one per post.
Thank you very much !
Semantically you want to make your relationships like so:
Work
// A work is of a single type
public function type()
{
return $this->belongsTo('App\Models\Type');
}
Type
// A type of work can have many items of work
public function works()
{
return $this->hasMany('App\Models\Work');
}
You can then access the relationship like so:
$type = Work::first()->type // return object of type Type
$works = Type::first()->works // return collection of objects of type Work
EDIT
By accessing the relationship with () you are returning the underlying query builder instance of the relationship and you will need to finish your statement with ->get() like so:
$works = Type::first()->works()->get();
You should have on Work Model:
public function type()
{
return $this->belongsTo('App\Models\Type');
}
and on your view:
$work->type->name;
Since you are not using default id as foreign key you should add
protected $primaryKey = "type_id";
in your model

How to define a hasMany far relationship

Suppose you have
Facility 1------* Section 1------* Session *------1 Event
I.e., a facility has many sections; each section can hold many sessions; each session belongs to an event.
How can I define this as a relationship in the Facility model to retrieve all unique instances of Event that a facility is hosting? I have tried this:
class Facility extends Eloquent\Model {
public function events() {
return $this->hasMany('Event')
->join('session', 'session.event_id', '=', 'event.id')
->join('section', 'section.id', '=', 'session.section_id')
->join('facility', 'facility.id', '=', 'section.facility_id');
}
}
I don't know if I'm very close with that; Laravel adds a constraint implicitly ("events"."facility_id" in (...)) and everything gets messed up.
What is the proper way of doing this?
I would avoid putting any logic in a relationship method on your models. Instead use eloquent to load your relationships, either one after the other or eager load into the Facility model. The latter being preferable.
class Facility extends Eloquent\Model
{
public function sections()
{
return $this->hasMany('Section');
}
}
Just make sure each of the models has the correct relationship set up so you can chain an eager load. Such as:
class Section extends Eloquent\Model
{
public function sessions()
{
return $this->hasMany('Session');
}
}
Then when you come to load the relationships you can use dot notation to eager load them.
$facility = Facility::with('sections.sessions.event')->get();
$facility will now contain a Facility model with nested relationships. You can use some of the different array helpers to extract/pluck all of the events.
This is the closer i've got to my initial purpose:
I created an SQL view:
CREATE VIEW facility_events AS
SELECT DISTINCT ON (e.id) e.id,
e.name,
e.created_at,
e.updated_at,
f.id AS facility_id
FROM events e
JOIN sessions s ON e.id = s.event_id
JOIN sections_extended fse ON s.section_id = fse.id
JOIN facilities f ON fse.root_facility_id = f.id;
Then I create the corresponding FactoryEvent Eloquent model and, finally, in my class Facility:
public function events() {
return $this->hasMany('App\FacilityEvent');
}
I look forward to see Laravel-only solutions for this. In other frameworks, such as Yii, I have been able to do things like that without the need to work on the database directly.

Sql error when using GORM's dynamic FindAllBy method - #2 is not set

I have those domain classes:
class Person{
String username
}
class Course {
String code
static hasMany = [events:Event]
}
class Event {
Long id
String name
(...)
static belongsTo = [course:Course, parallel:Parallel]
static hasMany = [teachers: Person, students: Person,bought: Exchange, sold: Exchange]
}
And what I want to do is find all the events associated with a student and a course. I did this query:
(...)
println "User: ${person.username}"
println "Course: ${course.code}"
Set<Person> persons = []
persons.add(person)
def events = Event.findAllByCourseAndStudents(course, persons)
}
But that is giving me an error ERROR util.JDBCExceptionReporter - Parameter "#2" is not set; SQL statement:
What am I missing here?
The issue with the second parameter in your query Students is the fact it's an 1:M (one to many) association and querying these associations using dynamic finders is not supported.
Take a look at this quick overview of the various types of querying supported by GORM/Grails to get a better understanding of what kind of options are available to you and when to use them.
As you can see using a criteria is really what you need in this case:
def events = Event.createCriteria().list() {
eq('course', course)
students {
eqId(person.id)
}
}
}
The above only matches against a single person, but you can modify this further to use a list of persons as you intend. I will leave that exercise to you so you can become familiar with how to create and use criteria.

Which relationship type to choose in Laravel Eloquent ORM on multiple relationships case

I am new to Laravel and a bit confused about some definitions of ORM.
I am currently working on a simple Trouble ticket management system, and here is my question :
(table: column, column,...)
tickets : id, description, equipment_id
equipments: id, name, vendor_id
vendor: id, name
This is a very short resume of my tables and its relations, following Laravel's conventions. How can I build these models?
Basically I need to retrieve, for example, how many tickets were opened to a certain vendor (how many times I called the vendor for support).
Thank you in advance
What zwacky said is entirely (edit: maybe not entirely correct in the end) true for close relations, but in your situation there is nested relation:
Vendor -> Equipment -> Ticket
Then to retrieve tickets for particular vendor you would define relation on Vendor model like this:
class Vendor extends Eloquent {
public function equipment()
{
return $this->hasMany('Equipment');
}
public function tickets()
{
return $this->hasManyThrough('Ticket', 'Equipment');
}
class Equipment extends Eloquent {
public function tickets()
{
return $this->hasMany('Ticket');
}
public function vendor()
{
return $this->belongsTo('Vendor');
}
class Ticket extends Eloquent {
public function equipment()
{
return $this->belongsTo('Equipment');
}
and to get count of total tickets for the vendor (not currently open):
Vendor::find($id) // retrieve particular vendor
->tickets()->count(); // get count on tickets table
// and this way you retrieve collection of related tickets
Vendor::find($id) // retrieve particular vendor
->tickets; // get Eloquent Collection
Also you may find it helpful: http://softonsofa.com/querying-relations-with-eloquent-in-laravel-4/
you'd need to declare these relationships within their models. e.g. your Ticket.php model could look like this:
class Ticket extends Eloquent {
public function equipment()
{
return $this->hasOne('Equipment');
}
public function vendor()
{
return $this->hasOne('Vendor');
}
...
}
for retrieval you'd do it like this:
foreach (Ticket::all() as $ticket) {
$ticket->vendor()->id;
}
check this section of the laravel docs.
edit: for the specific query how many tickets are open to a certain vendor:
Ticket::where('open', '=', 1)->vendor()->where('id', '=', 42);

Is there a way of using reference column name in doctrine 2?

I need to assing a value (a previously created entites Id)to reference column in a doctrine 2 model, For example
/**
* #Entity #Table(name="products")
*/
class product {
/**
*
* #ManyToOne(targetEntity="category")
*/
protected $category;
public function assignCategoryId($id) {
$this->category_id=$id;
}
}
I assume that category_id is created by doctrine 2 as referance column name,
Don't ask why I want to assign the id not the object itself, because it has to be this way. Is there a way to do this ? Any idea ?
While #Orbling's answer is correct you don't actually have to load the entity from the database. Instead you can use a reference:
// method on Product entity
public function setCategory(Category $category)
{
$this->category = $category;
}
// then set the category on the product
$product->setCategory($entityManager->getReference('category', $categoryId));
You can find the documentation here.
In order to do that, you would create a category entity and assign it to the relationship property.
$category = $entityManager->find('category', $categoryID);
$product = new product();
$product->category = $category;
That would create the relationship I believe.