residentSector:
columns:
id_resident_sector:
type: integer
primary: true
autoincrement: true
id_resident:
type: integer(8)
id:
type: integer(8)
date:
type: timestamp
residents:
columns:
id_resident:
type: integer(8)
primary: true
autoincrement: true
firstname:
type: string(50)
lastname:
type: string(50)
relations:
Sectors:
class: Sectors
local: id_resident
foreign: id
refClass: residentSector
Sectors:
columns:
id:
type: integer(4)
primary: true
autoincrement: true
sector_name:
type: string(50)
id_resp:
type: integer(4)
visibility:
type: integer(1)
I want to select all the "residents" of a given "sector" at à given date (the lastest date as example).
My problem is the date field is in the refclass (because it's the date of assignation) so
->where('residents.Sectors.date =max(residents.Sectors.date) ')
won't work obviously because the refclass is not part of the collection ..
what is the good way to define the doctrine relation so i can get the latest sector in date of a resident ?
Thanks in advance !
Unfortunately Doctrine doesn't provide any built-in way to achieve what you're trying to do. However many-to-many relationship in fact uses double one-to-many relationship.
So what you need is to is:
Make correct DQL query:
Doctrine_Query::create()
->from('Residents r')
->innerJoin('r.XXX rs WITH rs.date = ?', '08-04-2010')
->innerJoin('r.Sector s');
Where XXX is the name of ResidentSector table. I'm not quite sure whether its name will be same as table name, but you can get its name from table definition generated by Doctrine.
After you execute the query you will have to do all the mapping by your own, using Doctrine_Record::mapValue.
I dont know how to use doctrine but having many to many relationships results in an abundance of duplicate data.
You should maybe have 3 tables (residents, sectors, residentsToSectors) have date assigned in the residentToSectors table and then grab the information for either resident or sector based on whatever data you insert in the WHERE clause?
Related
Given this setup for my Doctrine 2 Entities:
App\Bundle\LorumBundle\Entity\Node:
type: entity
table: node
fields:
id:
id: true
type: integer
unsigned: false
nullable: false
generator:
strategy: IDENTITY
created:
type: datetime
inheritanceType: SINGLE_TABLE
discriminatorColumn:
name: type
type: string
length: 255
discriminatorMap:
a: a
b: b
c: c
App\Bundle\LorumBundle\Entity\A:
type: entity
fields:
status:
type: boolean
App\Bundle\LorumBundle\Entity\B:
type: entity
fields:
status:
type: boolean
App\Bundle\LorumBundle\Entity\C:
type: entity
fields:
title:
type: string
Now what I want to get is basically a mixed list of Entities of the type A & B (not C) with the status == true.
I could write a Query like this - using the instance ofoperator to limit the result to the subclasses i want of course but i will get an Error because the property I want to match against (status) is not mapped in the Superclass even tough all the Entities i want to match against have it:
$queryBuilder->select('Node');
$queryBuilder->from('App\Bundle\LorumBundle\Entity\Node','Node');
$queryBuilder->add('where',$queryBuilder->expr()->orx(
'Offer INSTANCE OF AppLorumBundle:A',
'Offer INSTANCE OF AppLorumBundle:B'
));
$queryBuilder->where($queryBuilder->expr()->eq('Node.status', '?1'));
$queryBuilder->setParameter(1, true);
$queryBuilder->orderBy('Node.created', 'asc');
$queryBuilder->setFirstResult( 0 );
$queryBuilder->setMaxResults( 200 );
Is there any way to do this, short of writing your own persister and hack it into Doctrine2?
Unfortunately its not an Option for me to just add the Information to the Superclass (in my real scenario this situation mostly applies to relations which i don't want to be loaded eagerly with every subclass)
You can use UNION and work with queries for entities A and B
build query for entity A
build query for entity B
build query for limit and order using UNION for queries A and B
no need to do any hacks for Doctrine library
I'm trying to model a user which could be invited by another user. So I set up one-to-many self reference in my doctrine model.
User:
tableName: users
actAs:
Timestampable:
columns:
id:
type: integer(11)
primary: true
autoincrement: true
name:
type: string(255)
unique: true
password:
type: string(255)
email:
type: string(255)
[...]
invited_by:
type: integer(11)
relations:
Inviter:
class: User
type: one
local: invited_by
foreign: id
foreignAlias: Invitees
onDelete: SET NULL
onUpdate: CASCADE
options:
type: InnoDB
collate: utf8_unicode_ci
charset: utf8
This works just fine in MySQL, but if I try to save the record using the User objects save()-method in Postgres the following error is thrown:
SQLSTATE[42P01]: Undefined table: 7 FEHLER: Relation »users_id«
existiert nicht LINE 1: SELECT CURRVAL('users_id') ^. Failing Query:
"SELECT CURRVAL('users_id')"
I think it is something related to the self reference, but I can't find a mistake in my modeling. Anyone an idea on this?
The default name of a sequence attached to a serial column is tablename_colname_seq
currval is for retrieving the "current value" of a sequence.
So it would have to be:
SELECT currval('users_id_seq')
Your whole syntax is obviously made out for MySQL. Things like type: InnoDB, integer(11) or autoincrement don't make sense in Postgres.
I have a entity called Container in a Symfony application, which I have included in the schema.yml file:
Container:
columns:
id: { type: integer, primary: true, autoincrement: true }
name: { type: string(127), notnull: true }
Strain:
columns:
id: { type: integer, primary: true, autoincrement: true }
...
container_id: { type: integer }
...
relations:
Container: { foreignAlias: Strains }
Then I have regenerated the models, forms and filters using the symfony doctrine:build --all-classes task.
Now when I try to use $strain->getContainer(), e.g. in a showSuccess action, it returns no object at all. I have double-checked that container_id has a reference to a record in container table.
Moreover, when I try to edit a Strain object and unlink the relationship with Container, the form is saved correctly, but the container_id column keeps the old value.
Do you know if Container is a reserved word or something like that in Symfony or Doctrine? What can be happening?
Thanks!
No, it isn't a reserved word.
(In fact, I have a model in my project with a Container relation).
Have you tried setting the local property on Container relation to container_id?
I want to attribute some tags to some of the objects of my doctrine model.
I found sfDoctrineActAsTaggablePlugin which seems to be precisely what I need.
The problem is that when I want to save a Taggable object, I get this error:
Unknown record property / related component "saved_tags" on "Mishidea"
Mishidea is the name of the class/table that I want to be Taggable.
Here is the related portion of my schema.yml file:
Mishidea:
connection: doctrine
actAs: {Timestampable: ~ , Taggable: ~ }
tableName: mishidea
columns:
idea_id:
type: integer(4)
primary: true
autoincrement: true
idea_title:
type: string()
notnull: true
primary: false
idea_summary:
type: string()
notnull: true
primary: false
idea_description:
type: string()
notnull: true
primary: false
idea_up:
type: integer(8)
notnull: true
default: 0
primary: false
idea_down:
type: integer(8)
notnull: true
default: 0
primary: false
idea_confirmation:
type: boolean(1)
default: false
primary: false
group_id:
type: integer(4)
notnull: false
primary: false
relations:
Mishgroup:
local: group_id
foreign: group_id
type: one
Ideacomment:
local: idea_id
foreign: idea_id
type: many
Mishdocument:
local: idea_id
foreign: idea_id
type: many
RelIdeafollower:
local: idea_id
foreign: idea_id
type: many
I also tried other types of syntax for the actAs attribute of the class such as:
actAs:
Timestampable: ~
Taggable: ~
and:
actAs:[Timestampable,Taggable]
But it's not the problem as I get :
$timestampable0 = new Doctrine_Template_Timestampable();
$taggable0 = new Taggable();
$this->actAs($timestampable0);
$this->actAs($taggable0);
in the BaseMishidea.php class of my model.
I don't understand why the Mishidea class doesn't get the attributes that the Taggable class should add to it since the model seems to add the behaviour via the $this->actAs() statement.
How to get this plugin working?
If that helps, I use Symfony 1.4 with MySQL/InnoDB and I had tried before with the PostgreSql DBMS, with the same result.
Your help would be much appreciated.
Thanks
FuzzyTern
EDIT1 - Regarding what said johnwards : Can anyone confirm that the Taggable behaviour is added in the schema.yml file via "actAs:", not "templates:"? That's what I read here and there (see my comment on johnwards' post) but since neither of both solutions work for me, I'm not sure. When using the "templates" keyword I get:
Unknown method Mishidea::addTag
and the specific classes of the model aren't generated.
EDIT2 - After a further investigation, I found that the Symfony stack trace is interresting.
Indeed, when I do:
$idea = new Mishidea();
$idea->save();
the TaggableListener is called (point 8 in the stack trace below), which shows that the relation is working. But then I don't understand what's going on and leads to the exception.
Stack trace:
1. at ()
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record/Filter/Standard.php line 55 ...
public function filterGet(Doctrine_Record $record, $name)
{
throw new Doctrine_Record_UnknownPropertyException(sprintf('Unknown record property / related component "%s" on "%s"', $name, get_class($record)));
}
}
2. at Doctrine_Record_Filter_Standard->filterGet(object('Mishidea'), 'saved_tags')
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 1374 ...
3. at Doctrine_Record->_get('saved_tags', 1)
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 1333 ...
4. at Doctrine_Record->get('saved_tags')
in n/a line n/a ...
5. at call_user_func_array(array(object('Mishidea'), 'get'), array('saved_tags'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/record/sfDoctrineRecord.class.php line 212 ...
6. at sfDoctrineRecord->__call('getSavedTags', array())
in n/a line n/a ...
7. at Mishidea->getSavedTags()
in SF_ROOT_DIR/plugins/sfDoctrineActAsTaggablePlugin/lib/TaggableTemplate.class.php line 93 ...
8. at TaggableListener->postSave(object('Doctrine_Event'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record/Listener/Chain.php line 237 ...
9. at Doctrine_Record_Listener_Chain->postSave(object('Doctrine_Event'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 355 ...
10. at Doctrine_Record->invokeSaveHooks('post', 'save', object('Doctrine_Event'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection/UnitOfWork.php line 112 ...
11. at Doctrine_Connection_UnitOfWork->saveGraph(object('Mishidea'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 1691 ...
12. at Doctrine_Record->save()
in SF_ROOT_DIR/apps/frontend/modules/idea/actions/actions.class.php line 24 ...
If someone wants to see the code for any point of the stack trace (only 1. is expanded here), just ask.
Any suggestion is welcomed.
Whoop whoop!!
I solved this problem, at last!
Well... The problem is that the sfDoctrineActAsTaggablePlugin plugin does work only for taggable objects which have an id property called precisely "id". I like to put the name of the entity in the name of my properties, that's why I called the idea of my taggable entity "idea_id".
As soon as I replaced "idea_id" by "id" everything worked like a charm (you may have several changes to do in the schema.yml and maybe even in the routing.yml file later on).
I don't know if I'm clear enough so don't hesitate to ask me further explanations.
Anyway that's a bit of a shame for this plugin, it is not generic enough (will report this to the developers).
BTW, all the syntaxes for actAs written in my first post are equivalent, use whichever you prefer.
Thank you all for your help, each reply was an encouragement without which I wouldn't have had the strength to find the bug ;).
Cheers
Possible Issues:
Make sure you have the plugin enabled
In ProjectConfiguration::setup, you should have
$this->enablePlugins(array(
'sfDoctrineActAsCommentablePlugin', //plus other plugins, like Doctrine
));
Set Up Your Schema Correctly
It should look like this:
ModelClass:
actAs:
Taggable:
columns: //etc
You should be using actAs not templates.
I don't believe you need to set an explicit relations for Tags, but I could be wrong about that. If you let me know, I will edit this answer.
Edit: Have you done a build all reload?
You need to add templates: [Taggable] to your schema not actAs.
Mishidea:
connection: doctrine
actAs: [Timestampable]
templates: [Taggable]
tableName: mishidea
columns:
idea_id:
type: integer(4)
primary: true
autoincrement: true
I want to attribute some tags to some of the objects of my doctrine model.
I found sfDoctrineActAsTaggablePlugin which seems to be precisely what I need.
The problem is that when I want to save a Taggable object, I get this error:
Unknown record property / related component "saved_tags" on "Mishidea"
Mishidea is the name of the class/table that I want to be Taggable.
Here is the related portion of my schema.yml file:
Mishidea:
connection: doctrine
actAs: {Timestampable: ~ , Taggable: ~ }
tableName: mishidea
columns:
idea_id:
type: integer(4)
primary: true
autoincrement: true
idea_title:
type: string()
notnull: true
primary: false
idea_summary:
type: string()
notnull: true
primary: false
idea_description:
type: string()
notnull: true
primary: false
idea_up:
type: integer(8)
notnull: true
default: 0
primary: false
idea_down:
type: integer(8)
notnull: true
default: 0
primary: false
idea_confirmation:
type: boolean(1)
default: false
primary: false
group_id:
type: integer(4)
notnull: false
primary: false
relations:
Mishgroup:
local: group_id
foreign: group_id
type: one
Ideacomment:
local: idea_id
foreign: idea_id
type: many
Mishdocument:
local: idea_id
foreign: idea_id
type: many
RelIdeafollower:
local: idea_id
foreign: idea_id
type: many
I also tried other types of syntax for the actAs attribute of the class such as:
actAs:
Timestampable: ~
Taggable: ~
and:
actAs:[Timestampable,Taggable]
But it's not the problem as I get :
$timestampable0 = new Doctrine_Template_Timestampable();
$taggable0 = new Taggable();
$this->actAs($timestampable0);
$this->actAs($taggable0);
in the BaseMishidea.php class of my model.
I don't understand why the Mishidea class doesn't get the attributes that the Taggable class should add to it since the model seems to add the behaviour via the $this->actAs() statement.
How to get this plugin working?
If that helps, I use Symfony 1.4 with MySQL/InnoDB and I had tried before with the PostgreSql DBMS, with the same result.
Your help would be much appreciated.
Thanks
FuzzyTern
EDIT1 - Regarding what said johnwards : Can anyone confirm that the Taggable behaviour is added in the schema.yml file via "actAs:", not "templates:"? That's what I read here and there (see my comment on johnwards' post) but since neither of both solutions work for me, I'm not sure. When using the "templates" keyword I get:
Unknown method Mishidea::addTag
and the specific classes of the model aren't generated.
EDIT2 - After a further investigation, I found that the Symfony stack trace is interresting.
Indeed, when I do:
$idea = new Mishidea();
$idea->save();
the TaggableListener is called (point 8 in the stack trace below), which shows that the relation is working. But then I don't understand what's going on and leads to the exception.
Stack trace:
1. at ()
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record/Filter/Standard.php line 55 ...
public function filterGet(Doctrine_Record $record, $name)
{
throw new Doctrine_Record_UnknownPropertyException(sprintf('Unknown record property / related component "%s" on "%s"', $name, get_class($record)));
}
}
2. at Doctrine_Record_Filter_Standard->filterGet(object('Mishidea'), 'saved_tags')
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 1374 ...
3. at Doctrine_Record->_get('saved_tags', 1)
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 1333 ...
4. at Doctrine_Record->get('saved_tags')
in n/a line n/a ...
5. at call_user_func_array(array(object('Mishidea'), 'get'), array('saved_tags'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/record/sfDoctrineRecord.class.php line 212 ...
6. at sfDoctrineRecord->__call('getSavedTags', array())
in n/a line n/a ...
7. at Mishidea->getSavedTags()
in SF_ROOT_DIR/plugins/sfDoctrineActAsTaggablePlugin/lib/TaggableTemplate.class.php line 93 ...
8. at TaggableListener->postSave(object('Doctrine_Event'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record/Listener/Chain.php line 237 ...
9. at Doctrine_Record_Listener_Chain->postSave(object('Doctrine_Event'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 355 ...
10. at Doctrine_Record->invokeSaveHooks('post', 'save', object('Doctrine_Event'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Connection/UnitOfWork.php line 112 ...
11. at Doctrine_Connection_UnitOfWork->saveGraph(object('Mishidea'))
in SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Record.php line 1691 ...
12. at Doctrine_Record->save()
in SF_ROOT_DIR/apps/frontend/modules/idea/actions/actions.class.php line 24 ...
If someone wants to see the code for any point of the stack trace (only 1. is expanded here), just ask.
Any suggestion is welcomed.
Whoop whoop!!
I solved this problem, at last!
Well... The problem is that the sfDoctrineActAsTaggablePlugin plugin does work only for taggable objects which have an id property called precisely "id". I like to put the name of the entity in the name of my properties, that's why I called the idea of my taggable entity "idea_id".
As soon as I replaced "idea_id" by "id" everything worked like a charm (you may have several changes to do in the schema.yml and maybe even in the routing.yml file later on).
I don't know if I'm clear enough so don't hesitate to ask me further explanations.
Anyway that's a bit of a shame for this plugin, it is not generic enough (will report this to the developers).
BTW, all the syntaxes for actAs written in my first post are equivalent, use whichever you prefer.
Thank you all for your help, each reply was an encouragement without which I wouldn't have had the strength to find the bug ;).
Cheers
Possible Issues:
Make sure you have the plugin enabled
In ProjectConfiguration::setup, you should have
$this->enablePlugins(array(
'sfDoctrineActAsCommentablePlugin', //plus other plugins, like Doctrine
));
Set Up Your Schema Correctly
It should look like this:
ModelClass:
actAs:
Taggable:
columns: //etc
You should be using actAs not templates.
I don't believe you need to set an explicit relations for Tags, but I could be wrong about that. If you let me know, I will edit this answer.
Edit: Have you done a build all reload?
You need to add templates: [Taggable] to your schema not actAs.
Mishidea:
connection: doctrine
actAs: [Timestampable]
templates: [Taggable]
tableName: mishidea
columns:
idea_id:
type: integer(4)
primary: true
autoincrement: true