Laravel Restful Controller ID - php

So to explain my issue, whenever i am connecting to the database with Laravel it will default search for the id column as "id".
If i name my column jobID for example, i would like to controller to search for "jobID" instead of just "id". I could just change all of my tables ID columns to "id" however this causes issues when you use Laravel's left joins as it will take the latest id column as the actual id column.
Heres my join:
$jobs = Job::leftJoin('occupational_areas', function($join) {
$join->on('jobs.occupationalArea', '=', 'occupational_areas.id');
})->get();
However Restful controller default to "id" and that is what i'm asking, how do i change the default "id" to becomes something more custom like jobID

Try using this left join
$jobs = Job::select('occupational_areas.id as occ_id', 'jobs.id as jobs_id', your required values)
->leftJoin('occupational_areas', 'jobs.occupationalArea', '=', 'occupational_areas.id')
->get();
comment for errors

Turns out the easiest way to do this is by setting:
protected $primaryKey = 'jobID';
Into your model.
I am pretty sure Ronser also had it right with his method. Either will work.
Thanks Ronser!

Related

How to get the name of an ID from other table [LARAVEL]

This query that I did is to fetch service_id and its count in ServiceOrder model:
$test = DB::table('serviceorders')
->select('serviceorders.service_id', DB::raw('COUNT(services.id) AS count'))
->join('services', 'serviceorders.service_id', '=', 'services.id')
->groupBy('serviceorders.service_id')
->whereMonth('serviceorders.created_at',Carbon::now("Asia/Kuala_Lumpur")->month)
->get();
I have no idea how to fetch the name of an id since it is at another model
Here's the result when I dd($test)
as you can see, it displays service_id because yeah I typed that but I don't know how to fetch the serviceName . also this way of query can be difficult if I'm trying to display it in a pie chart using chartJs (correct me if it is easy)
these are the tables involved
I am also looking for a right way to do this.
Here you go using Eloquent functions:
ServiceOrder::withCount('services')
->whereMonth('created_at', today()->month)
->having('services_count', '>', 0) // this is optional if you wish to avoid orders with 0 services
->get();
// now you will have this attribute `services_count`
// NOTE: Adjust your Carbon timezone within your `config/app.php` timezone to be 'Asia/Kuala_Lumpur'
It might not work if you don't have a relation (function) called services() within your ServiceOrder model, and for sure I guessed that this is your model name :) let me know if it was different so I can help out.

Pluck primaryKey from relationship between same table

Cursos has a many-to-many relationship with Cursos and i want to get only the primaryKey from the related Cursos.
$curso = Curso::with(['thumb','interna','area','cursos_relacionados' => function($query){
$query->pluck('curso_id');
}])->find($curso_id);
The problem: Column 'curso_id' in field list is ambiguous.
I could do this:
DB::table('cursos_has_cursos_relacionados')->select('curso_relacionado_id')
->where('curso_id','=',$curso_id)->pluck('curso_relacionado_id')->toArray();
But i would like to know if its possible and how to add a alias to the with() method and use the first sample of code.
UPDATE
This is the relation
public function cursos_relacionados(){
return $this->belongsToMany('App\Model\Curso','cursos_has_cursos_relacionados','curso_id','curso_relacionado_id');
}
The problem: Column 'curso_id' in field list is ambiguous.
You need to specify table: 'thumb.curso_id' or the table you want.
Unfortunately, i couldn't find anything about setting a alias on the with() method. But, if anyone finds himself here, loking for the same anwser. Try the following code, it should work just fine
$curso = Curso::with(['thumb.media_root','interna.media_root','objetivos_media.media_root','area'])->find($curso_id);
$curso->cursos_relacionados = DB::table('cursos_has_cursos_relacionados')->select('curso_relacionado_id')->where('curso_id','=',$curso_id)->pluck('curso_relacionado_id')->toArray();

Laravel Explicit route model binding issue in RouteServiceProvider

I am using Explicit route model binding for Slider module in my Laravel (5.6 version )application. Now I am facing an issue when i try to join sliders table with file_uploads table.
RouteServiceProvider
$this->bind('slider', function ($value) {
$slider = new Slider;
return Slider::withTrashed()
->leftjoin('file_uploads','file_uploads.file_code', '=', 'sliders.file_code')
->where('sliders.id', $value)->first();
});
this is the code am using.
Both sliders and file_uploads table have ID column. And in slider edit page am getting ID from file_uploads table. My intended ID will be from sliders table.
I really appreciate any help you can provide.
If you had used Eloquent Relationship it could have saved you having the one id property from a table override another due to joins.
But for the sake of using Joins then you can retrieve the needed id as another property using select() (see Selects) or passing the array parameters to the first() method so your code becomes:
return Slider::withTrashed()
->leftjoin('file_uploads','file_uploads.file_code', '=', 'sliders.file_code')
->where('sliders.id', $value)
->first(['*', 'sliders.id as sliders_id']);
Or:
return Slider::withTrashed()
->leftjoin('file_uploads','file_uploads.file_code', '=', 'sliders.file_code')
->where('sliders.id', $value)
->select('*', 'sliders.id as sliders_id')
->first();
Either way the select statement is passed as query and the id value is returned as sliders_id and you can use that where you needed the id instead.

Kohana add function return province name

I'm back again for another question, i'm trying and trying. But i can't get it fixed.
This is my issue;
I have a database table, with a ProvinceID this can alter from 1 to 12. But it's an ID of the province. The provinces are stored with the value pName in the table Provinces
I have the following code to alter the table, and join it with the preferences table
$veiling = ORM::factory('veilingen')
->select('veilingvoorkeur.*')
->join('veilingvoorkeur', 'LEFT')
->on('veilingen.id', '=', 'veilingvoorkeur.vId')
->find_all();
$this->template->content = View::factory('veiling/veilingen')
->bind('veiling', $veiling);
It displays correctly, in the view i have;
echo '<div class="row">';
foreach($veiling as $ve)
{
echo $ve->provincie;
}
?>
</div>
it displays the provincie id; but i want to add a function to it; So it will be transformed to a province name. Normally i would create a functions.php file with a function getProvince($provinceId)
Do a mysql query to grab the pName value from Provinces and that is the job. But i'm new to kohana. Is there an option to turn the province id to province['pName'] during the ORM selection part, or do i have to search for another solution. Which i can't find :(
So. Please help me on the road again.
Thanx in advance.
Kind regards,
Kevin
Edit: 1:08
I've tried something, and it worked. I used ORM in the view file, for adding a function;
function provincie($id){
$provincie = ORM::factory('provincies', $id);
return $provincie->pName;
}
But i'm not glad with this way of solution, is there any other way? Or am i have to use it this way?
Check out Kohana's ORM relationships. If you use this, you could access the province name by simply calling:
$ve->provincie->name;
The relationship definition could look something like:
protected $_belongs_to = array(
'provincie' => array(
'model' => 'Provincie',
'foreign_key' => 'provincie_id'
),
);
Note that if you have a table column called provincie the relationship definition I give above will not work. You'd either have to change the table column to provincie_id or rename the relationship to e.g. provincie_model.
The output you describe when you do echo $ve->provincie; suggests that you store the ID in a column called provincie, thus the above applies to you.
I'd personally go for the first option as I prefer accessing IDs directly with an _id suffix and models without any suffix. But that's up to you.
Edit: If you use Kohanas ORM relationships you could even load the province with the initial query using with() e.g:
ORM::factory('veiling')->with('provincie')->find_all();
This could save you hundreds of extra queries.

Laravel Eloquent: How to get only certain columns from joined tables

I have got 2 joined tables in Eloquent namely themes and users.
theme model:
public function user() {
return $this->belongs_to('User');
}
user model:
public function themes() {
return $this->has_many('Theme');
}
My Eloquent api call looks as below:
return Response::eloquent(Theme::with('user')->get());
Which returns all columns from theme (that's fine), and all columns from user (not fine). I only need the 'username' column from the user model, how can I limit the query to that?
Change your model to specify what columns you want selected:
public function user() {
return $this->belongs_to('User')->select(array('id', 'username'));
}
And don't forget to include the column you're joining on.
For Laravel >= 5.2
Use the ->pluck() method
$roles = DB::table('roles')->pluck('title');
If you would like to retrieve an array containing the values of a single column, you may use the pluck method
For Laravel <= 5.1
Use the ->lists() method
$roles = DB::table('roles')->lists('title');
This method will return an array of role titles. You may also specify a custom key column for the returned array:
You can supply an array of fields in the get parameter like so:
return Response::eloquent(Theme::with('user')->get(array('user.username'));
UPDATE (for Laravel 5.2)
From the docs, you can do this:
$response = DB::table('themes')
->select('themes.*', 'users.username')
->join('users', 'users.id', '=', 'themes.user_id')
->get();
I know, you ask for Eloquent but you can do it with Fluent Query Builder
$data = DB::table('themes')
->join('users', 'users.id', '=', 'themes.user_id')
->get(array('themes.*', 'users.username'));
This is how i do it
$posts = Post::with(['category' => function($query){
$query->select('id', 'name');
}])->get();
First answer by user2317976 did not work for me, i am using laravel 5.1
Using with pagination
$data = DB::table('themes')
->join('users', 'users.id', '=', 'themes.user_id')
->select('themes.*', 'users.username')
->paginate(6);
Another option is to make use of the $hidden property on the model to hide the columns you don't want to display. You can define this property on the fly or set defaults on your model.
public static $hidden = array('password');
Now the users password will be hidden when you return the JSON response.
You can also set it on the fly in a similar manner.
User::$hidden = array('password');
user2317976 has introduced a great static way of selecting related tables' columns.
Here is a dynamic trick I've found so you can get whatever you want when using the model:
return Response::eloquent(Theme::with(array('user' => function ($q) {
$q->addSelect(array('id','username'))
}))->get();
I just found this trick also works well with load() too. This is very convenient.
$queriedTheme->load(array('user'=>function($q){$q->addSelect(..)});
Make sure you also include target table's key otherwise it won't be able to find it.
This Way:
Post::with(array('user'=>function($query){
$query->select('id','username');
}))->get();
I know that this is an old question, but if you are building an API, as the author of the question does, use output transformers to perform such tasks.
Transofrmer is a layer between your actual database query result and a controller. It allows to easily control and modify what is going to be output to a user or an API consumer.
I recommend Fractal as a solid foundation of your output transformation layer. You can read the documentation here.
In Laravel 4 you can hide certain fields from being returned by adding the following in your model.
protected $hidden = array('password','secret_field');
http://laravel.com/docs/eloquent#converting-to-arrays-or-json
On Laravel 5.5, the cleanest way to do this is:
Theme::with('user:userid,name,address')->get()
You add a colon and the fields you wish to select separated by a comma and without a space between them.
Using Model:
Model::where('column','value')->get(['column1','column2','column3',...]);
Using Query Builder:
DB::table('table_name')->where('column','value')->get(['column1','column2','column3',...]);
If I good understood this what is returned is fine except you want to see only one column. If so this below should be much simpler:
return Response::eloquent(Theme::with('user')->get(['username']));
#You can get selected columns from two or three different tables
$users= DB::Table('profiles')->select('users.name','users.status','users.avatar','users.phone','profiles.user_id','profiles.full_name','profiles.email','profiles.experience','profiles.gender','profiles.profession','profiles.dob',)->join('users','profiles.user_id','=','users.id')
->paginate(10);
Check out, http://laravel.com/docs/database/eloquent#to-array
You should be able to define which columns you do not want displayed in your api.

Categories