问题
Let say I have 2 tables with column like this:
table_a: (with a corresponding model TableA)
id | (20+ other field) | deleted_at | created_at | updated_at
table_b: (with a corresponding model TableB)
id | a_id | ( 30+ other field ) | deleted_at | created_at | updated_at
Now I am using laravel and join on this two table
$result = TableA::join('table_b', 'table_a.id', '=', 'table_b.a_id')
->where('table_b.created_at', '>=', date('Y-m-d'))
->get();
The problem is that I am not able to some field of table_b when the column name are the same as table_a. (i.e. id
, deleted_at
, created_at
and updated_at
)
I have done some search, and from this question on stackoverflow, I may do:
$result = TableA::join('table_b', 'table_a.id', '=', 'table_b.a_id')
->where('table_b.created_at', '>=', date('Y-m-d'))
->select('table_b.id as b_id', 'table_b.created_at as b_created_at')
->get();
However, when using this method, I need to add all the column name into the select statement, and it is painful to do that on 50+ fields. It is an exporting function so all fields are necessary. Is there a way I can make the necessary rename without listing all other field that don't need a rename to retrieve all the rows? Or is there a way I can retrieve all the row without a rename?
P.S. I am using laravel 4. This is an old project and updating is even more painful than listing all fields.
回答1:
Unfortunately Eloquent queries do not alias the fields from joined tables so the columns with the same name overwrite each other.
The obvious solution would be to rename the columns which is not always a viable option.
Another solution would be getting rid of joins and use whereHas method of a query builder, that allows filtering data based on data in related models. As it uses subselects instead of joins, no columns get overwritten.
All you'd need to do is defining a relation table_b in your TableA model with:
class TableA extends Model {
public function table_b() {
return $this->hasOne(TableB::class); //or hasMany, depending on your data model
}
}
and replacing:
$result = TableA::join('table_b', 'table_a.id', '=', 'table_b.a_id')
->where('table_b.created_at', '>=', date('Y-m-d'))
->get();
with
$result = TableA::whereHas('table_b', function($query) {
$query->where('created_at', '>=', date('Y-m-d');
});
That would give you all TableA records that have a related TableB record that matches given criteria.
来源:https://stackoverflow.com/questions/39361125/how-to-get-all-column-with-some-having-same-name-when-using-laravel-eloquent