In my application (developed with Symfony 1.4 and Doctrine) I'm trying to get all users based on idempresa of the user logged in. idempresa is in a sf_guard_user_profiletable and this is the schema for that:
SfGuardUserProfile:
connection: doctrine
tableName: sf_guard_user_profile
columns:
id: { type: integer(8), primary: true }
user_id: { type: integer(8), primary: false }
idempresa: { type: integer(4), primary: false }
relations:
User:
local: user_id
class: sfGuardUser
type: one
foreignType: one
foreignAlias: SfGuardUserProfile
onDelete: CASCADE
onUpdate: CASCADE
I'm trying with this query:
Doctrine_Core::getTable('sfGuardUser')
->createQuery('u')
->leftJoin('u.Profile p')
->where('idempresa = ?', $id_empresa)
->execute();
But get this error:
Unknown relation alias Profile
What is wrong in my code?
Your relation between the sfGuardUser and sfGuardUserProfile is not called Profile but SfGuardUserProfile. So you should use in your query builder:
->leftJoin('u.SfGuardUserProfile p')
Related
In Symfony 1.4, Doctrine I have this snippet from schema.yml
Attendance:
columns:
id: { type: integer(4), primary: true, autoincrement: true }
user_id: { type: integer(4) }
relations:
JoomlaUser: { class: JosUser, local: user_id, foreignAlias: AttendanceList }
and
JosUser:
tableName: jos_users
columns:
id: { type: integer(4), primary: true, autoincrement: true }
relations:
AttendanceList: { class: Attendance, local: id, foreign: user_id }
What is the most efficient way to determine from JosUser that there are no Attendance records. I tried model/doctrine/JosUser.class.php
count($this->getAttendanceList())
but this returns a Doctrine Record with all fields empty but user_id
Schema :
JosUser:
tableName: jos_users
columns:
id: { type: integer(4), primary: true, autoincrement: true }
relations:
AttendanceList: { type: many, class: Attendance, local: id, foreign: user_id }
With type: many, getAttendanceList() should return a Doctrine_Collection (see the JosUser base class in lib/model/doctrine/base/BaseJosUser.class.php), then you can use
$this->getAttendanceList()->count()
I have just created a new project with a many-to-many relation (User-Group) and the code below.
As you can guess in the code I'm trying to assign manually groups to a user, but it doesn't assign it anything...any idea?
User:
columns:
id:
type: integer(4)
autoincrement: true
primary: true
username:
type: string(255)
password:
type: string(255)
attributes:
export: all
validate: true
Group:
tableName: group_table
columns:
id:
type: integer(4)
autoincrement: true
primary: true
name:
type: string(255)
relations:
Users:
foreignAlias: Groups
class: User
refClass: GroupUser
GroupUser:
columns:
group_id:
type: integer(4)
primary: true
user_id:
type: integer(4)
primary: true
relations:
Group:
foreignAlias: GroupUsers
User:
foreignAlias: GroupUsers
The code is this:
public function executeIndex(sfWebRequest $request)
{
$user = Doctrine_Core::getTable('User')->find(1);
$groups = Doctrine_Core::getTable('Group')->findAll();
$user->setGroups($groups);
$user->save();
$this->forward('default', 'module');
}
Try defining the relation in the User entity too (and don't using foreingAlias in Groups). Also use the local and foreign fields.
So, schema.yml should look like:
User:
...
relations:
Groups:
class: Group
refClass: GroupUser
local: user_id
foreign: group_id
Group:
...
relations:
Users:
class: User
refClass: GroupUser
local: group_id
foreign: user_id
If that doesn't work, I think you can set the groups with the Doctrine "link" method.
See Record.php (probably in lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine folder)
Example:
$groups_ids = array();
foreach($groups as $group) $groups_ids[] = $group->getId();
$user->link('Groups',$groups_ids);
Also, if you are trying only to add instances to that relation (and you hate the person who will fix your code in the future) you can create N-GroupUsers
Example:
foreach($groups as $group) {
$ug = new GroupUser();
$ug->setUserId($user->getId());
$ug->setGroupId($user->getId());
$ug->save();
}
Please, use the first option and let me know if any of this works for you!
I've got the following schema.yml file, but it's just not working correctly. Can anyone point me in the right direction please?
ClientPaymentService:
actAs: { Timestampable: ~ }
columns:
clientId: integer
name: { type: string(100), notnull: true, unique: true }
paymentServiceId: integer
config: { type: string(4096), notnull: true }
cardFormatId: integer
relations:
Client:
local: clientId
foreign: id
type: many
foreignType: one
foreignAlias: Client
PaymentService:
local: paymentServiceId
foreign: id
type: many
foreignType: one
foreignAlias: ClientPaymentService
CardFormat:
local: cardFormatId
foreign: id
type: many
foreignType: one
foreignAlias: ClientCardFormats
CountryCode:
class: CountryCode
refClass: ClientPaymentServiceCountryCode
foreign: id # country_code_id also doesn't work
local: id
ClientPaymentServiceCountryCode:
columns:
client_payment_service_id:
type: integer
primary: true
country_code_id:
type: integer
primary: true
relations:
ClientPaymentService:
local: client_payment_service_id
foreign: id
foreignAlias: ClientPaymentServiceCountryCodes
CountryCode:
local: country_code_id
foreign: id
foreignAlias: ClientPaymentServiceCountryCodes
CountryCode:
actAs: { Timestampable: ~ }
columns:
name: { type: string(100), notnull: true, unique: true }
code: { type: string(10), notnull: true, unique: true }
relations:
ClientPaymentService:
class: ClientPaymentService
refClass: ClientPaymentServiceCountryCode
local: id
foreign: id # client_payment_service_id also doesn't work
I receive the following error when trying to save something in the admin area:
Unknown record property / related component "id" on "ClientPaymentServiceCountryCode"
Thanks
Try this association:
ClientPaymentService:
.....
CountryCode:
class: CountryCode
refClass: ClientPaymentServiceCountryCode
foreign: country_code_id # country_code_id also doesn't work
local: client_payment_service_id # you must define both directions
ClientPaymentServiceCountryCode:
columns:
client_payment_service_id:
type: integer
primary: true
country_code_id:
type: integer
primary: true
// you not have to define relations here
CountryCode:
....
ClientPaymentService:
class: ClientPaymentService
refClass: ClientPaymentServiceCountryCode
local: country_code_id
foreign: client_payment_service_id
I have just follow documentation :
http://www.doctrine-project.org/projects/orm/1.2/docs/manual/defining-models/ru#relationships:join-table-associations:many-to-many
How can I implement pagination using Doctrine_Pager or sfDoctrinePager while my query selects multiple columns from two or more tables ?
Edit1:
Ok, now I figured out that it can be done how Nathan has described below! I got confused as I couldn't retrieve certain data from the query! Let me describe it below:
This is my pager query:
$pager = new sfDoctrinePager('sfGuardUser', '5');
$q = Doctrine_Query::create()
->select('u.id, u.username, p.org_name, g.name, l.status')
->from('sfGuardUser u')
->leftJoin('u.Profile p')
->leftJoin('u.Groups g')
->leftJoin('u.LicensedVendors l')
->where('g.name = \'client\'');
$pager->setQuery($q);
$pager->setPage($request->getParameter('page', 1));
$pager->init();
Now in my Template I can retrieve my sfGuardUser and Profile data like this:
foreach ($pager->getResults() as $data) {
echo $data->username ; //outputs 'username' from sfGuardUser table
echo '<br />' ;
echo $data->Profile->org_name ; //outputs 'Organization name' from sfGuardUserProfile table
}
I was wrongly trying to retrieve the profile data by $data->org_name and not $data->Profile->org_name! Now its working for this part correctly, but there is still an issue !
I am still unable to retrieve the Groups & LicensedVendors data using $data->Groups->name or $data->LicensedVendors->status ! It does not show any error or any value either! looks like it outputs an empty string. Shouldn't it get the value just like Profile data ?
But when I hydrate the query by setting:
$q->setHydrationMode(Doctrine_Core::HYDRATE_SCALAR);
I can retrieve all data through:
foreach ($pager->getResults() as $data) {
echo $data['u_username'];
echo $data['p_org_name'];
echo $data['g_name'];
echo $data['l_status'];
}
How to get those data without setting **Doctrine_Core::HYDRATE_SCALAR** ? Where I'm doing wrong for retrieving those Groups and LicensedVendors table data?
Here is the schema definition of the tables described above:
License:
actAs: [Timestampable]
tableName: licenses
columns:
id:
type: integer(4)
primary: true
notnull: true
autoincrement: true
status:
type: enum
values: ['approved','pending_admin','pending_client','pending_vendor','rejected']
default: 'pending'
client_id:
type: integer(8)
notnull: true
vendor_id:
type: integer(8)
notnull: true
product_desc:
type: clob(16777215)
supplier_name:
type: string(80)
other_desc:
type: string(50)
financial_statement:
type: clob
relations:
VendorUser:
class: sfGuardUser
local: client_id
foreign: id
foreignAlias: LicensedVendors
onDelete: cascade
foreignType: many
owningSide: true
ClientUser:
class: sfGuardUser
local: vendor_id
foreign: id
foreignAlias: LicensedClients
onDelete: cascade
foreignType: many
owningSide: true
sfGuardUser:
actAs: [Timestampable]
columns:
first_name: string(255)
last_name: string(255)
email_address:
type: string(255)
notnull: true
unique: true
username:
type: string(128)
notnull: true
unique: true
algorithm:
type: string(128)
default: sha1
notnull: true
salt: string(128)
password: string(128)
is_active:
type: boolean
default: 1
is_super_admin:
type: boolean
default: false
last_login:
type: timestamp
indexes:
is_active_idx:
fields: [is_active]
relations:
Groups:
class: sfGuardGroup
local: user_id
foreign: group_id
refClass: sfGuardUserGroup
foreignAlias: Users
sfGuardUserProfile:
actAs:
Timestampable: ~
columns:
user_id:
type: integer
notnull: true
email:
type: string(80)
notnull: true
unique: true
email_new:
type: string(80)
unique: true
firstname:
type: string(30)
lastname:
type: string(70)
org_name:
type: string(80)
notnull: true
relations:
User:
class: sfGuardUser
foreign: id
local: user_id
type: one
onDelete: cascade
foreignType: one
foreignAlias: Profile
sfGuardGroup:
actAs: [Timestampable]
columns:
name:
type: string(255)
unique: true
description: string(1000)
relations:
Users:
class: sfGuardUser
refClass: sfGuardUserGroup
local: group_id
foreign: user_id
foreignAlias: Groups
Edit2: I posted my new issues which I described in first edit as a separate question here !
I guess as long as your query gives back a Doctrine_Collection object, you can use it with a pager, can't you?
Yeah, what greg0ire said. This documentation is a bit old, but it shows what you'd need with Propel in the old days. Updating to Doctrine would be like,
public function executeList ()
{
$pager = new sfDoctrinePager('Comment', 2);
$q = Doctrine_Core::getTable('Comment')
->createQuery('c')
->where('c.author = ?', 'Steve')
->leftJoin('c.Article a')
->andWhere('a.content LIKE ?', '%enjoy%')
->orderBy('c.created_at ASC');
$pager->setQuery($q);
$pager->setPage($request->getParameter('page', 1));
$pager->init();
$this->pager = $pager;
}
This blog post, "Symfony doctrine pager for two tables" has a more extended/convoluted example. Oh, looks like that was the author's answer to his own SO question.
I'm setting up my first symfony project, and am having trouble with the schema. I'm not sure if I'm going about it the right way.
I'm having a problem with two of my classes. I have Clients, which can have many Contacts, one of the contacts needs to be selected as the invoice contact. This is my schema:
NativeClient:
actAs: { Timestampable: ~ }
columns:
name: { type: string(255), notnull: true }
address: { type: string(255) }
postcode: { type: string(9) }
tel: { type: string(50) }
fax: { type: string(50) }
website: { type: string(255) }
client_status_id: { type: integer, notnull: true, default: 0 }
priority: { type: boolean, notnull: true, default: 0 }
invoice_contact_id: { type: integer }
invoice_method_id: { type: integer }
relations:
NativeContact: { local: invoice_contact_id, foreign: id, foreignAlias: NativeInvoiceContacts }
NativeClientStatus: { local: client_status_id, foreign: id, foreignAlias: NativeContacts }
NativeInvoiceMethod: { local: invoice_method_id, foreign: id, foreignAlias: NativeClientStatuses }
NativeContact:
actAs: { Timestampable: ~ }
columns:
client_id: { type: integer, notnull: true }
name: { type: string(255), notnull: true }
position: { type: string(255) }
tel: { type: string(50), notnull: true }
mobile: { type: string(50) }
email: { type: string(255) }
relations:
NativeClient: { onDelete: CASCADE, local: client_id, foreign: id, foreignAlias: NativeClients }
NativeClientStatus:
actAs: { Timestampable: ~ }
columns:
name: { type: string(255), notnull: true }
NativeInvoiceMethod:
actAs: { Timestampable: ~ }
columns:
name: { type: string(255), notnull: true }
If i remove the following line (and associated fixtures) it works, otherwise I get a segmentation fault.
NativeContact: { local: invoice_contact_id, foreign: id, foreignAlias: NativeInvoiceContacts }
Could it be getting in a loop? Trying to reference the Client and the Contact over and over? Any help would be greatly appreciated! Thanks!
Darren
Old question I know, but heres a follow up solution. Sometimes Doctrine will throw this error for seemingly no reason whatsoever. Im sure there is an underlying reason, but we dont all have time to debug the entire Doctrine source.
Try specifying --env=[your env], and it may just work - has for me.
Darren, it seems like you're defining the relationship at both ends while using conflicting criteria...
NativeContact: { local: invoice_contact_id, foreign: id, foreignAlias: NativeInvoiceContacts }
...relationship is between "invoice_contact_id" and undeclared "id" PK in NativeContact.
NativeClient: { onDelete: CASCADE, local: client_id, foreign: id, foreignAlias: NativeClients }
... same relationship is between "client_id" and undeclared "id" PK in NativeClient.
I personally only define these in one end and let Doctrine handle the rest, but it depends on what you're trying to achieve here. If ONE client HAS MANY contacts, you could drop the second declaration and define the relationship in the clients table only and add "type: many, foreignType: one" to state that it's a one-to-many relationship.