Laravel, mysql query with join in model class - php

laravel creates its own model for each table. Since it is one of the most popular frame work, we gone for it. Most of our mysql queries are based on multiple tables, we use join and we write those queries in controller itself. Can some one tell us, how to handle queries with multiple tables in model class.
Thanks in advance.

You have to define relation in your model class, For information regarding relationship see here
E.g. If I want to access State name, in my City page then:
Controller:
$city = App::make('Platform\Storage\City\CityRepository')->view($city_id, false, [], ['state'=>array('id', 'name')])
Repository:
public function view($id, $active=true, $fields=array(), $with=array()) {
$query = $this->model->newQuery();
$tableName = $this->model->getTable();
if ($active) {
$query->where($tableName . '.is_active', '=', 1);
}
if (!$fields) {
$fields = array($tableName . '.*');
}
if ($with) {
$with = $this->model->processWithSelects($with);
$query->with($with);
}
try {
return $query->with($with)->where($tableName . '.id', '=', $id)->first($fields);
}
catch (Exception $e) {
throw new DBException($e->getMessage(), $e->getCode(), $e->getPrevious());
}
}
City Model:
public function state() {
return $this->belongsTo('State');
}
For more info, visit these: Tutorial on Repository, Laravel Query, Simple CRUD
In your Controller, create a constructor:
public function __construct(Model $model) {
parent::__construct();
$this->model = $model; // Model $model, means IOC or Dependancy Injection
}
Then do: $this->model->function_in_your_model(), to execute your model functions.
See, if that helps.

Related

How to query a polymorphic Eloquent model providing the type and the id?

I have a polymorphic model Discussion and other models that are discussable.
I have configured my morph map to translate project to App\Models\Company\Project which is discussable.
I would like to write:
function get_all_discussions($type, $id)
{
return Discussion::orderBy('created_at', 'desc')
->where('discussable_type', $type)
->where('discussable_id', $id)
->get();
}
get_all_discussion('project', 1232);
Unfortunately ->where('discussable_type', $type) does not work with the morph map.
My current solution is to use this kludge:
function getMorphType($typeOrClass)
{
$morphMap = array_flip(\Illuminate\Database\Eloquent\Relations\Relation::morphMap());
return array_get($morphMap, $typeOrClass, $typeOrClass);
}
A better approach could be defining relationships in the models: https://laravel.com/docs/5.8/eloquent-relationships#polymorphic-relationships
For example I got Project and Issue, two models that could be discussable.
class Project
{
public function discussions()
{
return $this->morphMany(Discussion::class, 'discussable');
}
}
class Issue
{
public function discussions()
{
return $this->morphMany(Discussion::class, 'discussable');
}
}
Then if you want to get all discussion for a project or an issue:
$project = Project::findOrFail(101);
$issue = Issue::findOrFail(102);
$project->discussions;
$issue->discussions;

How to apply relationship with two id's in laravel

So I have a model called data_storage and another model entity_states
I have to fetch the record from data_storage with entity_states where entity_state has data_storage_id and state_id.
How can I use eloquent to achieve this ?.
Or Ill have to use Query builder and use innerJoin?
Update1
My Actual Query
$this->values['new_leads'] = $data_storages->with('actions','states','sla')->where('wf_id',$wfid)->get();
My data_storage modal
class data_storages extends Model
{
//
protected $fillable = ['layout_id','member_id','company_id','team_id','data','status','wf_id'];
function actions()
{
return $this->hasMany('App\Models\ActionDataMaps', 'data_id', 'id' );
}
function states()
{
return $this->hasOne('App\Models\workflow_states','id','status');
}
function sla()
{
//Here I have to get those row from entity_states model where , data_storage_id and state_id
}
}
Thanks
Here's the more reasonable way to do it:
class DataStorage extends Model {
public states() {
return $this->belongsToMany(State::class,"entity_states");
}
}
class State extends Model {
public storages() {
return $this->belongsToMany(DataStorage::class,"entity_states");
}
}
Then you can eager-load related models via e.g.:
$storage = DataStorage::with("states")->first();
$storage->states->first()->column_in_related_state;
Or via the state:
$state = State::with("storages")->first();
$state->storages->first()->column_in_related_storage;
If there are additional columns in the pivot table entity_states then you can refer to them in the relationship as e.g.:
public states() {
return $this->belongsToMany(State::class)->withPivot("pivot_column");
}
In your model data_storage you can define a property / method entity_states to get them:
class data_storage extends Model
{
public function entity_states()
{
return $this->hasMany('App\entity_states','data_storage_id')->where('state_id ','=',$this->table());
}
}
Then you can access them in an instance by
$entityStatesOfDataStorage = $yourDataStorageInstance->entity_states;
See this link:
https://laravel.com/docs/5.3/eloquent-relationships
for Query Builder you may use this:
DB::table('data_storage')
->join('entity_states','data_storage.data_storage_id','=','entity_states.state_id')
->get();
For your reference Laravel Query Builder

Aggregate distant relationship with eloquent

I have two models User and Child.
class User extends Model {
public function children() {
return $this->belongsToMany('App\Child', 'user_child')->withPivot('relation_id');
}
public function connections() {
// How to get the distinctly aggregate of my children.friends.contacts as a relationship here?
}
}
class Child extends Model {
public function contacts() {
return $this->belongsToMany('App\User', 'user_child')->withPivot('relation_id');
}
public function friends() {
return $this->belongsToMany('App\Child', 'child_connection', 'child_id1', 'child_id2');
}
}
I would like to eagerly load the distant relationship which I name 'connections' which are the contacts (users) of my children's friends.
$user = User::with('children', 'children.friends', 'connections');
Any ideas how to do this elegantly?
Thank you!
Try
public function connections() {
return $this->belongsToMany('App\Child', 'user_id')->with('friends.contacts;);
}
OMG What a long shot!
If by any miracle that works, then doing
$user = User::find(1);
$user->connections(); //should bring 'children', 'friends' and 'contacts' in one query.
Well it should.
If you find an answer, please post it. I'm really interested in this.

Get laravel data with relation between tables

I have the following data models:
class Cliente extends Model
{
public function sector()
{
return $this->belongsTo(Sector::class,'sectoresId');
}
}
class Sector extends Model
{
public function sectorLanguage()
{
return $this->hasMany(SectorLanguage::class,'sectoresId');
}
public function cliente()
{
return $this->hasMany(ClienteLanguage::class,'sectoresId');
}
}
class SectorLanguage extends Model
{
public function sector()
{
return $this->belongsTo(Sector::class,'sectoresId');
}
public function idioma()
{
return $this->belongsTo(Idioma::class,'idiomasId');
}
}
I want to recover all the active clients and the name of the sector to which it belongs, if I do something like this
$cliente = Cliente::where('active','1');
When I run $client I can not enter the attribute
foreach($cliente as $cli) {
$cli->sector->sectorLanguage->nombre;
}
Why? It only works for me when I find it by id
$cliente = Cliente::find(1);
echo $cliente->sector->sectorLanguage->nombre;
How can I get what I need without resorting to doing SQL with Query Builder.
Thank you very much, greetings.
According to your defined relations, the Sector has many sectorLanguage, it means you're receiving a collection, so you should work on an object like this:
$cliente->where('active', 1)
->first()
->sector
->sectorLanguage
->first()
->nombre;
Cliente::where('active', 1) and sectorLanguage gives you the collection, so you
should first get the first item from $cliente & sectorLanguage and then apply the
desired relationship
Hope it should work!

laravel 5.1 : how can i get nested relation from model?

I have a question about laravel model relations and use them in eloquent class . my question is this :
I have a model like this :
class TransferFormsContent extends Model
{
public function transferForm()
{
return $this->belongsTo('App\TransfersForms','form_id');
}
}
and in transferForm i have other side for this relation like this :
public function transferFormsContent()
{
return $this->hasMany('App\TransferFormsContent', 'form_id', 'id');
}
also in transferForm i have another relation with employee like this :
class TransfersForms extends Model
{
public function employee()
{
return $this->belongsTo('App\User','employee_id');
}
}
now if I want get a record from "TransferFormsContent" with its "transferForm " provided its with employee. how can i do this?
i now if i want get "TransferFormsContent" with only "transferForm " i can use from this :
$row = $this->model
->with('transferForm');
but how about if i want transferForm also be with its employee?
ok i find that:
only you can do that with this :
$row = $this->model
->with('transferForm.employee')
now you have a record from "TransferFormsContent" with its "transferForm " provided its with employee.
You can use nested eager loading with dot notation:
$row = $this->model
->with('transferForm.employee');
Or you can use closure:
$row->$this->model
->with(['transferForm' => function($q) {
$q->with('employee')
}]);
Second method is useful when you need to sort or filter by employee

Categories