Is there a way to set an alias to columns using Eloquent? - laravel

Suppose I have a model for a table in which the columns are written in Portuguese. In this way:
class Order extends Model
{
use HasFactory;
protected $fillable = [
'nota_id', 'identificacao'
];
//more..
}
Currently, to set and get values I do as follows:
$order = new Order();
$order->nota_id = 1;
$order->identificacao = '123456';
echo $order->nota_id;
echo $order->identificacao;
Rename columns directly in the table is not an option. But I need to do something like this:
$order = new Order();
$order->invoiceId = 1;
$order->identification = '123456';
echo $order->invoiceId;
echo $order->identification;
And at the end, when I save to the database using eloquent, "invoiceId" and "identification" will be converted to "nota_id" and "identificacao".
Are there any packages that solve this problem?

Your problem can be solved with laravel mutators.
Inside your model you can create mutator/accessor functions (for retrieving & setting values based on your needs) like:
getInvoiceIdAttribute($value)
{
return $this->attributes['nota_id'];
}
getIdentificationAttribute($value)
{
return $this->attributes['identificacao'];
}
Pay attention to the naming i used it's not a random name for your function. The structure must be:
get + the name you want + Attribute
Read more about laravel mutators here
Then to access them you simple do what you did in your expected behaviour:
echo $order->invoiceId;
echo $order->identification;

Related

Laravel - can I make models dynamically and have relationships on each generated model?

I need to create Models based on the alphabet as their tables names are like 'products_a', 'products_b'....'products_z'. But I don't want to create all these models as separated files,
but want to find a way to use all these tables dynamically.
And all tables are separated based on some 'shopping-mall id' values.
I've found a solution to set tables dynamically like this solution.
So what I tried before was like below.
class Products extends Model
{
use BindsDynamically;
public $timestamps = false;
public $fillable = [ 'product_name', 'reg_time'];
public static function newProduct($mall_id)
{
$rangeArr = range('a', 'z');
$product = new Products;
foreach ($rangeArr as $ar) {
if (strtolower(substr($mall_id, 0, 1)) == $ar) {
$product->setTable('product_'.$ar);
}
}
return $product;
}
}
However, now I created a Cart model and tried to use the relationship methods with all the separated tables which I cannot.
So I realized I need the separated models with relationships not just tables.
Theoretically, my database has those tables.
products_a
products_b
....
products_z
products_cart
So, the products_cart table needs to have all the products tables idx data.
I want to use relationships like 'hasMany' or 'belongsTo', therefore I need all the separated models.
Can I make all the alphabetical models dynamically and use relationship methods?
If so, how can I do this?
OK, I understand we have a nasty DB design here. But then, we don't have a DB expert and I cannot figure what can I do about this DB design.
So, please don't judge about the DB design, rather guide the better way to replace it.
Maybe you UNION all product tables and overwrite the models newModelQuery() method to achieve that
class Products extends Model
{
use BindsDynamically;
public $timestamps = false;
public $fillable = [ 'product_name', 'reg_time'];
/**
* Get a new query builder that doesn't have any global scopes or eager loading.
*
* #return \Illuminate\Database\Eloquent\Builder|static
*/
public function newModelQuery()
{
$query = parent::newModelQuery();
$rangeArr = range('a', 'z');
foreach ($rangeArr as $ar) {
//if (strtolower(substr($mall_id, 0, 1)) == $ar) {
$query->union('product_'.$ar);
//}
}
return $query;
}
}
But that's probably just one of a couple methods you'd have to overwrite this way. And this solution currently doesn't support your $mall_id. But after all, it's due to bad database design.

eloquent get all row of a table and edit a field

I'm a newbie on laravel and I'm trying to use Eloquent to edit a field for all rows of a MySQL table.
So I create that:
<?php
namespace App\Http\Controllers;
use App\Mining;
use DB;
class FrontendController extends Controller{
public function cronDiff(){
$basic = GeneralSettings::first();
$row = Mining::all()->whereStatus(1)->get();
foreach ($row as $coins){
$code = Mining::where('coin_code', $coins->coin_code)->get();
$risultato = difficolta($code);
DB::table['minings']->insert('coin_code' => $code);
}
}
}
And I have a table minings like this:
id->int
name->varchar
coin_code->varchar
coin_diff->varchar
status->tinyint
But I can't update coin_diff using the value of $risultato (taken from other function)
Can you help to find out where I'm wrong?
Thanks.
try to use ->update('coin_code' => $code); instead ->insert
I think this solution would be better:
$minings = DB::table('minings')->get();
$minings->coin_code = $code;
$minings->update();
It should work like that: Mining::update(['coin_code' => $code]) if you have conditions you can chain them before update.
Also, you need to have the columns on models $fillable property. So, i don't know what error do you get but it might be from that.
If you want to update then why are you using insert?!
If you want to update a single row then modify your code
DB::table['minings']->insert('coin_code' => $code);
to
$coins->update(['coin_code' => $risultato]);
And make sure that $risultato have string value

how to filter related tables by date in Laravel?

I have 2 related tables and I need to filter the date of a table by month
My first table have the following fields: Id_agendamien_persona , Id_agendamiento, id_persona
The second table have the following fields: Id_agendamiento, fecha
so I need to filter fecha in the second table,
Mi controller
public function listar(){
$contactos = Contacto::pluck('completo','id_contacto');
$contacto_x_agendamientos = Contacto_x_Agendamiento::all();
array_add($contactos,0,"::Seleccione::");
return view('agendamiento.listar')->with(compact('contacto_x_agendamientos','contactos'));
}
My model
first table
class Contacto_x_Agendamiento extends Model
{
protected $table = "contacto_x_agendamiento";
protected $primaryKey = 'id_contacto_x_agendamiento';
const CREATED_AT = 'fecha_creado';
const UPDATED_AT = 'fecha_modificado';
public function Agendamiento(){
return $this->hasOne(Agendamiento::class,'id_agendamiento','id_agendamiento');
}
}
second table
class Agendamiento extends Model
{
protected $table = "agendamiento";
protected $primaryKey = 'id_agendamiento';
const CREATED_AT = 'fecha_creado';
const UPDATED_AT = 'fecha_modificado';
public function scopeMes($query){
return $query->whereMonth('fecha_agendar','=',date('m'))->get();
}
}
View
<td>{{$contacto_x_agendamiento->Agendamiento->Mes()->fecha_agendar}}</td>
error
Property [fecha_agendar] does not exist on this collection instance.
The issue here, is that you're trying to fetch the property of an Agendamiento model from a Collection that you're getting back as a result.
Here you have two choices. You either get just one model, by using ->first():
echo $contacto_x_agendamiento->Agendamiento->Mes()->first()->fecha_agendar;
Or you iterate the Collection and print each fecha_agendar property:
foreach ($contacto_x_agendamiento->Agendamiento->Mes()->get() as $agendamiento) {
echo $agendamiento->fecha_agendar;
}
On a side note, you should totally rethink your coding style/conventions. I'm fully aware it works, but having id_contacto_x_agendamiento as a primary id or a class name like Contacto_x_Agendamiento isn't best practice.
Having a mix of English and Spanish in classes/properties/variables could also be avoided, to improve other people's readability.

Eloquent not selecting date attributes when using where clause

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.

Counting number of occurrence of a specific string using Magento collection?

I have mapped my custom table with Magento, so that i can fetch all data in it using below
Mage::getModel('custom/filter')->getCollection();
Below is the sample table i have mapped
filter_id filters
------------------
1 5,6,5
3 77,8,5,77
10 22,55,33
I need to count the number of occurence of a specific string under field filters in this table using collection.
say for example, if i want to count occurence of 77 in 2nd row (filter_id = 3).
How do i do it with model collection?
I know i can use query to directly query the database using query methods in magento, but i am trying to do this in collection way.
Any suggestions would be helpful.
Thanks,
Balan
If I am understanding this correctly, the way that I would go about it would be to put your logic into the model. Simply put, you will make your selection like so:
$filter_id = 3;
$query = 77;
$collection = Mage::getModel('custom/filter')->getCollection();
$collection->addFieldToFilter('filter_id', $filter_id); // Hopefully it will be more than just one
foreach($collection as $filterModel) {
$filterModel->getOccurrences($query);
}
/////****** Company/Custom/Model/Filter.php ******////////
<?php
class Company_Custom_Model_Filter extends Mage_Core_Model_Abstract
{
protected function _construct()
{
$this->_init('custom/filter');
}
public function getOccurrences ($value)
{
$exploded = explode(',', $this->getFilters());
$count = 0;
foreach($exploded as $explodedValue) {
if ($explodedValue === $value) $count++;
}
return $count;
}
}
And, if you wanted to refactor this code into a collection, it will be pretty much the same iterator, going through each model. It is just a matter of where the initial code is called from.

Resources