cakephp update a record in a different model / table - cakephp

I am in a Model1 (Model1)and I need to run some business logic that should update a record in the Model2 (table2).
Here is the query/action I need to run from Model1 in Model2
$sql ="update table2 SET products = $product WHERE `id` = '".$id."'";
How would I go about doing it?

If the two models are related, you can save data to two tables at the same time. See the book for information on how to use Model::saveAll(). This is how you would represent that query though:
$this->Model2->id = $id;
$this->Model2->saveField('products', $product);

if the 2 models are not related (no relationship), Model->query() is a quick and dirty way. Otherwise, if Model1 has a relationship to Model2, in Model1, you can refer to Model2 by : $this->Model2->function_you_need_to_call()

Related

Database Model Design With Laravel Eloquent

we have a problem to query our database in a meant-to-be fashion:
Tables:
employees <1-n> employee_card_validity <n-1> card <1-n> stamptimes
id id id id
employee_id no card_id
card_id timestamp
valid_from
valid_to
Employee is mapped onto Card via the EmployeeCardValidity Pivot which has additional attributes.
We reuse cards which means that a card has multiple entries in the pivot table. Which card is right is determined by valid_from/valid_to. These attributes are constrained not to overlap. Like that there's always a unique relationship from employee to stamptimes where an Employee can have multiple cards and a card can belong to multiple Employees over time.
Where we fail is to define a custom relationship from Employee to Stamptimes which regards which Stamptimes belong to an Employee. That means when I fetch a Stamptime its timestamp is distinctly assigned to a Card because it's inside its valid_from and valid_to.
But I cannot define an appropriate relation that gives me all Stamptimes for a given Employee. The only thing I have so far is to define a static field in Employee and use that to limit the relationship to only fetch Stamptimes of the given time.
public static $date = '';
public function cardsX() {
return $this->belongsToMany('App\Models\Tempos\Card', 'employee_card_validity',
'employee_id', 'card_id')
->wherePivot('valid_from', '>', self::$date);
}
Then I would say in the Controller:
\App\Models\Tempos\Employee::$date = '2020-01-20 00:00:00';
$ags = DepartmentGroup::with(['departments.employees.cardsX.stamptimes'])
But I cannot do that dynamically depending on the actual query result as you could with sql:
SELECT ecv.card_id, employee_id, valid_from, valid_to, s.timestamp
FROM staff.employee_card_validity ecv
join staff.stamptimes s on s.card_id = ecv.card_id
and s.stamptimes between valid_from and coalesce(valid_to , 'infinity'::timestamp)
where employee_id = ?
So my question is: is that database desing unusual or is an ORM mapper just not capable of describing such relationships. Do I have to fall back to QueryBuilder/SQL in such cases?
Do you suit your database model towards ORM or the other way?
You can try:
DB::query()->selectRaw('*')->from('employee_card_validity')
->join('stamptimes', function($join) {
return $join->on('employee_card_validity.card_id', '=', 'stamptimes.card_id')
->whereRaw('stamptimes.timestamp between employee_card_validity.valid_from and employee_card_validity.valid_to');
})->where('employee_id', ?)->get();
If your Laravel is x > 5.5, you can initiate Model extends the Pivot class I believe, so:
EmployeeCardValidity::join('stamptimes', function($join) {
return $join->on('employee_card_validity.card_id', '=', 'stamptimes.card_id')
->whereRaw('stamptimes.timestamp between employee_card_validity.valid_from and employee_card_validity.valid_to');
})->where('employee_id', ?)->get();
But code above is only translating your sql query, I believe I can write better if I know exactly your use cases.

How to apply condition to Laravel eloquent relation

I have a ProcessHistory and Person model I need a eloquent code for relation with multiple condition.
Conditions:
1. oindex = oindex
2. pat_id = pat_id
I want a eloquent code to get result of the following sql code
select * from tbl_process_history as s join tbl_persons as p on (s.oindex = p.oindex and s.pat_id = p.pat_id)
I need to get all the persons having same oindex and pat_id. I have tried with below eloquent code where I can apply condition inside of relation 'own'. Here I can apply only for as static value.
ProcessHistory::with(['own'=>function($query){
return $query->where('pat_id','');
}])->get();
I need a condition inside of relation where I can match pat_id of process history model with persons model.
I just found that I was actually searching for relationship with composite key but this feature is not provided in laravel. It can be solved by using https://github.com/topclaudy/compoships package.
ProcessHistory::with(['own'=>function($query) use ($param){
return $query->where('pat_id',$param);
}])->get();

Cakephp. How do i access other columns of a table if the only referenced column of that table is the id column

i have TableA referencing id column of TableB as foreign key. The code below outputs the id of TableB, so i want to use this id to access the rest of the columns of this entity. How do i do that?
Thi is the index.ctp below
<td><?= $tableA->has('tableB') ? $this->Html->link($tableA->$tableb_id->, ['controller' => 'TableA', 'action' => 'view', $tableA->TableB->id]) : '' ?></td>
CakePHP 3.0 will attach associated tables to each Entity using an underscore singular naming convention (for BelongsTo, and underscore plural for hasMany) when using the contain feature.
So in your controller you would find records like this.
public function index() {
$tableA = $this->TableA->find()->contain('TableB')->first();
$this->set(compact('tableA'));
}
The above will find the first record, and also the associated TableB record. We can see this by using the debug feature.
$tableA = $this->TableA->find()->contain('TableB')->first();
debug($tableA->toArray());
In your view you can access the TableB as a property of $tableA
// will output the association TableB
debug($tableA->table_b_id); // the ID column
debug($tableA->table_b); // all of TableB columns
You should learn the Cake bake features on the command line, as this will add #property annotations to the entity classes for associations.
You can bake TableA like this
$ bin/cake bake model TableA
Which will create src/Model/Entity/TableA.php and src/Model/Table/TableATable.php
For the TableA.php entity it will have a comment block like this.
/**
* #property int id
* // more properties
*
* #property \App\Model\Entity\TableB $table_b
*/
class TableA extends Entity {
// ...
}
As long as you follow Cake's conventions, and use the Bake features. A lot of this can be setup for you. Making it easier to find associated data. These #property features also enable autocomplete features in PhpStorm, Eclipse and other IDEs for PHP.

Need to order by properties in the reference property, any good solution?

Say I have 2 kind:
class Account(db.Model):
name = db.StringProperty()
create_time = db.DataTimeProperty()
last_login = db.DateTimeProperty()
last_update = db.DataTimeProperty()
class Relationship(db.Model)
owner = db.ReferenceProperty(Account)
target = db.ReferenceProperty(Account)
type = db.IntegerProperty()
I want to get the equivalence of following query:
SELECT target
FROM Relationship
WHERE owner = :key AND type = :type
ORDERBY target.last_login DESC
How to do that?
reference: http://www.mail-archive.com/google-appengine#googlegroups.com/msg15878.html
There's no equivalent for that query in datastore. Some points:
You can't select a single property. SELECT is always SELECT * (you select a whole entity).
You can't do joins. You need to denormalize your models to fit the queries you will perform, or perform multiple queries.
So to achieve your goal, you need to have last_login stored in Relationship, or have a 3rd model to serve as index for that specific query.

how to display table value from another controller in cakephp

I have one CompanyConroller connect with companies table.
how can i get companies table value via calling from SubadminController?
You can get companies table value by calling SubadminController by giving this relation in Subadmin model
var $belongsTo = array("Company");
or
var $hasMany = array("Company");

Resources