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();
Is there a way to select only specific columns when using "with" with eloquent?
My problem is that i am getting a very long list of accounts and i also need to get their websites using the relation "with", but the "websites" object is big and it makes the request very slow.
I tried using:
$accounts = $accounts->with('websites')->select(['account_id','url']);
And also:
$accounts = $accounts->with('websites', function($query) {
$query->select(['account_id','url']);
});
And they both didn't work.
I didn't see an answer for this in their documentation, so if there is a way i would really appreciate if someone would share it with me. Also if there is an alternative for "with" that can give the same result it will be great as well. Thanks.
$accounts = $accounts->with([
'websites' => function($query) {
$query->select(['account_id','url']);
}
]);
Try to define the columns on your relationship:
class Account
{
public function websites()
{
return $this->hasMany('App\Website')->select(['account_id','url']);
}
}
Please note that the class and the relation is only for demonstrating purposes, try to add this ->select(['account_id','url']) on your relation.
I need help with Laravel 5 (using Eloquent)
I have 2 tables...
Model Driver
drivers
id
company
Model DriverOnline
drivers_online
id
name
driver_id
I need to search for a result on (company=1 and driver_id=driver.id).
Please help me!
If you want to only fetch Driver based on a condition, you can just do this:
Driver::with('online')->where('company', 1)->get();
If the clause is on the relationship, use with and specify a query on that.
$company = 1;
$drivers = Driver::with(['online' => function($query) use ($company)
{
$query->where('company', $company);
}]);
See "Eager Load Constraints":
https://laravel.com/docs/5.0/eloquent
Take note of my use. This allows you to include variables from the scope into your Closure instance.
And be aware, if you use either solution, you must set up a relationship. Consult the link I shared with more information on that.
Edit: As per our conversation.
$drivers = Driver::where('company_id','=',1)
->with('driversOnline')
->whereHas('driversOnline', function($query) {
$query->where('online','=',1);
})
->get();
I have a Objective model which has many Action and every Action has one ActionYear. already defined in model.
How to use orderby to sort action in objective through action_year's specific column.
$query = Objective::with('actions.actionYear')
->orderBy('action_year.created_at')
->get();
this through error Undefined table: 7 ERROR: missing FROM-clause entry for table "action_year".
How to solve this. Thank you.
You can order the eager loaded models with a closure:
$query = Objective::with(['actions.actionYear' => function($q){
$q->orderBy('action_year.created_at');
})->get();
If you use function with() then this only makes sure the named relationship is loaded also to avoid extra need for SQL queries later. Othewise it does not introduce any additional changes compared to Objective::all()
One way how to achieve sorted collection is to use sortBy() function after loading the data like this
$query = $query->sortBy(function($objective){
return $objective->actionYear->created_at;
});
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.