I'm facing this strange issue with my Eloquent queries.
My model looks like this one:
class MyModel extends Model {
// ...
$protected $dates = [
"some_date",
]
}
When using a query like this one:
$myModel = MyModel::find(1);
echo $myModel->toJson();
I get this output:
{
"id" : 1
"some_date" : "../../../"
}
But when I use this query:
$myModel = MyModel::where('id', '=', 1)->get();
echo $myModel->toJson();
I get this strange output:
{
"id" : 1
}
The where clause isn't selecting the date attributes! Why is it happening?
Either one of two ways to do this:
If there is a $hidden array defined on the model, make sure it does not include this column.
--OR--
If there is no $hidden array, make sure there is no $visible array and if there is a $visible array defined make sure the columns you want are in it.
Laravel removes columns that are hidden or not visible when serializing to json.
Related
Considering that the model is
class Cota extends Model
{
protected $fillable = ['status','user_id','produto_id','numero','arquivo','updated_at'];
protected $dates = [
'updated_at',
];
//protected $dateFormat = 'd/m/Y';
}
And considering the query:
$cotas = DB::table('cotas')->join('produtos','produtos.id','=','cotas.produto_id')->join('users','users.id','=','cotas.user_id')->select('cotas.id','produtos.titulo as produto','cotas.numero','cotas.arquivo','users.name','cotas.status','cotas.updated_at','produtos.valor')->get();
When I get only one instance, like:
$cota = Cota::find(6517);
I can do this:
$cota->updated_at->format('d/m/Y');
But in the query above, the results come always with the traditionl date format used by Mysql.
How do I get the results with the ('d/m/Y') format? I have to use a raw query? Is that the only way?
Thanks!
You can always user DB::raw in Select statement.
$cotas = DB::table('cotas')
->join('produtos','produtos.id','=','cotas.produto_id')
->join('users','users.id','=','cotas.user_id')
->select([
'cotas.id',
'produtos.titulo as produto',
'cotas.numero',
'cotas.arquivo',
'users.name',
'cotas.status',
DB::raw('DATE_FORMAT(cotas.updated_at, "%d/%m/%Y"') as updated_at,
'produtos.valor'
])
->get();
// Or Else You can always loop over your collection when displaying data / using that data.
You can use date casting like so
protected $casts = [
'updated_at' => 'datetime:d/m/Y',
];
This is only useful when the model is serialized to an array or JSON according to the docs.
I'm trying to retrieve data from database and bind them to a html select tag, and to bind them i need to use pluck so i get the field i want to show in a array(key => value), because of FORM::select. The normal pluck gets all the results, while i want to use distinct. My model is Room and it looks like:
class Room extends Eloquent
{
public $timestamps = false;
protected $casts = [
'price' => 'float',
'floor' => 'int',
'size' => 'float'
];
protected $fillable = [
'capacity',
'description',
'price',
'floor',
'size',
'type',
'photo_name'
];
}
While my function I'm using in the controller look like:
public function getRooms()
{
$roomType = Room::pluck('type','type');
$roomFloor = Room::pluck('floor','floor');
return view('roomgrid')->with('type',$roomType)->with('floor',$roomFloor);
}
And my view contains this piece of code to get floors:
{{FORM::select('floor', $floor, null,['class'=>'basic'])}}
Like this i get duplicated floors, that i don't want. Is there any way so i can get distinct floors and pluck them? Thanks in advance.
Why not use groupBy()?
$roomType = Room::groupBy('type')->pluck('type','type');
Room::unique('floor')->pluck('floor', 'floor');
distinct can do the trick:
Room::query()->distinct()->pluck('type');
Which will be translated into the following SQL:
SELECT DISTINCT type FROM rooms
2019 Update
You don't need to use 2 arguments with pluck()
simply do:
$roomType = Room::groupBy('type')->pluck('type');
of course for getting it into array:
$roomType = Room::groupBy('type')->pluck('type')->toArray();
Sometimes I use the result for whereIn clause, its useful for that.
you can do this
$roomType = Room::pluck('type')->unique();
$roomFloor = Room::pluck('floor')->unique();
You can use KeyBy or pluck with same key-Value pair to pick Distinct Values.
PHP array can only have unique keys.From this Idea we can get Unique models based on Array key.
Room::keyBy('floor')->pluck('floor');
or
Room::pluck('floor', 'floor');
I use the following code to insert multi array to database:
foreach($request->category as $k => $v){
$category[] = array(
"category_id" => $v,
"announcement_id" => $announcement->id
);
}
AnnouncementCategory::insert($category);
So, input data is POST array $request->category.
I need to refactoring this code
I tried this code:
$announcement->categories()->attach($request->category);
In model Announcement I have:
public function categories()
{
return $this->hasMany("App\AnnouncementCategory", "announcement_id", "id");
}
If you define in your Announcement model relationship like this:
public function categories()
{
return $this->belongsToMany(AnnouncementCategory::class);
}
you can do it like this:
$announcement->categories()->attach($request->category);
EDIT
I see you updated your question and added categories relationship. But looking at your code, AnnounceCategory is rather pivot table, so you should use belongsToMany as I showed instead of hasMany
You can do it in one line if the request matches the columns:
AnnouncementCategory::insert($request->all());
Then in your AnnouncementCategory model, make sure you declare the protected $fillable array where you specify which field could be populated.
Is it possible to return an value for an hasOne relation directly with an Model?
For example:
$List = Element::orderBy('title')->get();
The Element has a "hasOne" Relation to an column:
public function type()
{
return $this->hasOne('App\Type', 'id', 'type_id');
}
How can i now return automatically the "type" for the Model?
At the Moment i am looping through all Elements, and build my own "Array" of Objects, including the Key of "type" in this example. But ill prefer to do this only in my Model.
Ill know how to add a "normal" property, but can it be someone from an relation?
public function getTypeAttribute($value)
{
return // how ?
}
protected $appends = array('type');
Is this possible?
Edit:
A workaround could be to use DB:: to return the correct value - but ill dont thing thats a good workaround: like:
public function getTypeAttribute($value)
{
// make a query with $this->type_id and return the value of the type_name
}
protected $appends = array('type');
you need to eager load your relations when getting the Element:
$list = Element::with('type')->orderBy('title')->get();
then access the type using
foreach ($list as $item) {
echo $item->type->type_name;
}
where type_name would be the name of a column in the types table
Make a query scope and in that scope, join your attributes from other tables.
http://laravel.com/docs/5.1/eloquent#query-scopes
http://laravel.com/docs/5.1/queries#joins
I want to return a JSON of an Eloquent model, but I'd like to change the array keys. By default they are set as the table field names, but I want to change them.
For example if I have a users table with two fields : id and user_name
When I return User::all(); I'll have a JSON with "[{"id" => 1, "user_name" => "bob}] etc.
I'd like to be able to change user_name to username. I haven't found the way to do it without an ugly foreach loop on the model.
I'm not sure why you would want to do this in the first place and would warn you first about the structure if your app/would it be better to make things uniform throughout.. but if you really want to do it.. you could do:
$user = User::find($id);
return Response::json(array('id' => $user->id, 'username' => $user->user_name));
That will return a JSON object with what you want.
You can also change the name of the key with:
$arr[$newkey] = $arr[$oldkey];
unset($arr[$oldkey]);
Just have a look at robclancy's presenter package, this ServiceProvider handles those things you want to achieve.
GITHUB LINK
Just set the $hidden static for you model to the keys you want to hide:
class User extends Eloquent
{
public static $hidden = 'id';
}
and name them the way you like with get and set functons.