Cakephp join condition error - sql

I have two tables employees and posting.
employees with fields id,name
AND
postings with fields id,employee_id,status
Now to retrieve all the employees(with posting details) whose Posting.status = 1, I wrote in PostingsController.php's view() action:
$cond = array('Posting.status'=>1);
$e = $this->Employee->find('all',array('conditions' => $cond));
$this->set('emp',$e);
In Employee.php model var $hasMany = 'Posting';
In Posting.php model var $belongsTo = 'Employee';
But the above code generates an error like :
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column
'Posting.status' in 'where clause'
Generated SQL:
SQL Query: SELECT `Employee`.`id`, `Employee`.`name` FROM `cakelab`.`employees` AS `Employee` WHERE `Posting`.`status` = 1
I am new to CakePhp joins, please guide me.

Cake doesn't join the tables when the relation type is hasMany. Rather it performs a query on the first table (employees) and with the id of the employee it performs a second query on postings table to retrieve all the postings related to that employee
you can manually join the tables but I suggest querying on postings table and then group by Employee
$this->Posting ->find(
'all',
array(
'fields' => array('Employee.id', 'Employee.name', 'Posting.status' ),
'conditions' => $cond,
'group' => array('Employee.id')
)
);

Related

Laravel Eloquent Getting Many To Many Relations Per Pivot Table Field Condition

I have a problem with Laravel 7 Eloquent. I have 2 tables joined by many to many relation. Table user is connected to PaymentModule by pivot table PaymentModuleUser. I need to use where on pivot table on statement is_active = 1. When i use toSQL() in my model SQL returns good results but when i check my Eloquent Query in Controller, data that i revicive ignore my wherePivot method (return all data from table ignoring is_active = 1 field subscribers = null and get me this user.. I must do it if my pivotWhere = null dont show this user). Could you point me where i get wrong with my code?
My UserTable model:
public function subscriber(){
return $this->belongsToMany(PaymentsModule::class, 'payment_module_user', 'user_id')->withPivot('is_active');
}
MyController:
$users = User::with(['subscriber'=>function($query)
{
$query->wherePivot('is_active','=', 1);
}])->get();
print_r($users);
Try with
$users = User::with('subscriber' => function($query) {
$query->where('payment_module_user.is_active', 1);
})->get();
print_r($users);
The pivot table is already joined by eloquent, so just start using it
Found it here.
In your controller, try using this
$query->wherePivot('is_active', 1);
Instead of,
$query->wherePivot('is_active','=', 1);

PostgreSQL multi-table query with name, first_name, and last_name

I have two tables in my PostgreSQL database.
One table, call it 'Archive', has a column 'name' which are two-word first-name and last-name, e.g. 'John Smith' and an empty column which wants to be full of 'user_id'.
The second table, call it 'User Accounts', has three columns, one 'first_name' and one 'last_name' and one 'id'.
My goal is to implement a query that uses the column in Archive to select for the corresponding first_name and last_name in User Accounts and return to Archive the 'id' into 'user_id' column
You can use a join. For instance:
select a.*, ua.id as user_id
from archive a left join
user_accounts ua
on a.name = ua.first_name || ' ' || ua.last_name;
If you actually want to update the column:
update archive a
set user_id = ua.id
from user_accounts ua
where a.name = ua.first_name || ' ' || ua.last_name;
Note that name matching can be quite tricky. You may not get as many matches as you expect. If this turns out to be an issue, ask another question. Include sample data and desired results in the question.

MetaColumns() for a MS SQL view?

I am trying to use ADODB to work with a MS SQL database containing views.
MetaColumns() works well with tables, but returns an empty array when I use a view name as the parameter. Further research shows that $metaColumnsSQL uses sys.tables object for resolving column names, so it doesn't appear to be intended for views. Is there a way to obtain column names for a view object?
ADOdb cannot provide a metaColumns() object for a view because it's basis is the interrogation of the schema for the objects associated with a single table.
You can emulate metaColumns() with a view by using the fetchField() method as follows, using NorthWind:
$SQL = " CREATE VIEW vEmpTerritories AS
SELECT employees.employeeId, EmployeeTerritories.TerritoryId
FROM employees, EmployeeTerritories
WHERE EmployeeTerritories.employeeId = employees.employeeId";
$db->execute($SQL);
$SQL = "SELECT * FROM vEmpTerritories";
$f = $db->execute($SQL);
$recordSet = $db->Execute($SQL);
$cols = $recordSet->fieldCount();
for($i=0;$i<$cols;$i++){
$fld = $recordSet->FetchField($i);
print_r($fld);
}
This would return an array of ADOfieldObjects with basic information about each column:
ADOFieldObject Object
(
[name] => employeeId
[max_length] =>
[type] => int
[column_source] => employeeId
)
ADOFieldObject Object
(
[name] => TerritoryId
[max_length] => 20
[type] => nvarchar
[column_source] => TerritoryId
)
Unfortunately, the data returned from fetchfield() is not as detailed as from metaColumns but it may be sufficient for your needs.

active record select - ambiguous column name

I have this statement which gets an error because both phone and area_code are active record types with an id. Here I want to select the area_code id:
area_code_rec = #phone.area_codes.select(:id).where(:areacode => area_code).last
ActiveRecord::StatementInvalid: ActiveRecord::JDBCError: Ambiguous column name 'id'
I believe you can specify which table the id is from like this:
area_code_rec = #phone.area_codes.select('phones.id').where(:areacode => area_code).last
Or use 'area_codes.id'.
It may be smart not to use a string name, rather directly the table name from your Model.
so, using some of Ruby's MetaProgramming magic:
area_code_rec = #phone.area_codes.select("#{AreaCode.table_name}.id").where(:areacode => area_code).last
area_code_rec = #phone.area_codes.select('area_codes.id').where(areacode: area_code).last
I am assuming the name of the area codes table is area_codes. If it is singular for some reason, it would be ...select('area_code.id')...

Fluent nHibernate Mapping with Ternary Mapping Table

Have a legacy database with mapping table structures like the following. I am trying to figure out how to fluently map this type of relationship.
There are multiple parent tables that use a mapping table to store notes.
The parent tables look like the following:
P1 Table
ID iSomething
P2 Table
ID iSomethingElse
There is a mapping table that will take a parent table and map it to a note table.
Mapping Table
ID i_RecordUniqueID
ID i_NoteID
ID i_RecordID
The column i_RecordID contains a numeric value indicating which parent table the i_RecordUniqueID value came from. The mapping table only has those three columns and is a ternary primary key.
Here is the note table:
Note Table
ID i_NoteID
The query to find table P1's notes is as follows:
Select n.*
from P1 p
inner join Mapping m on p.iSomething = m.i_RecordUniqueID and m.i_RecordID = 1
inner join Note n on m.i_NoteID = n.i_NoteID
The query to find table P2's notes is as follows:
Select n.*
from P2 p
inner join Mapping m on p.iSomething = m.i_RecordUniqueID and m.i_RecordID = 2
inner join Note n on m.i_NoteID = n.i_NoteID
In my Parent tables mapping file, I have an association like the below. I don't know how to add the i_RecordID constraint.
HasManyToMany<Note>(x => x.Notes)
.Table("Mapping")
.ParentKeyColumn("i_RecordUniqueID")
.ChildKeyColumn("i_NoteID")
.Cascade.All();
FluentNHibernatew does not yet support ManyToAny mapping. you could map it for readonly access
// P1Map()
HasManyToMany(x => x.Notes)
.Table("Mapping")
.ParentKeyColumn("i_RecordUniqueID")
.Where("i_RecordID == 1")
.ChildKeyColumn("i_NoteID")
.Cascade.All();
// P2Map()
HasManyToMany(x => x.Notes)
.Table("Mapping")
.ParentKeyColumn("i_RecordUniqueID")
.Where("i_RecordID == 2")
.ChildKeyColumn("i_NoteID")
.Cascade.All();
or you have to create a component
ICollection<TableToNote> Notes;
public TableToNoteMap()
{
ReferencesAny(x => x.Parent).IdentityColumn("i_RecordUniqueID").MetaTypeColumn("i_RecordID")...;
References(x => x.Note);
}