symfony - sfDoctrineGuard - loading fixture data - symfony1

I'm currently using the sfDoctrineGuardPlugin and sfForkedDoctrineApplyPlugin and when I reload data using doctrine:data-load
I get the following:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (my_db.sf_guard_user_profile, CONSTRAINTsf_guard_user_profile_user_id_sf_guard_user_id_1FOREIGN KEY (user_id) REFERENCESsf_guard_user(id) ON DELETE CASCADE)
This is really annoying as I can't seem to load any of the records that are in my fixtures.
I've copied the schema from the sfForkedDoctrineApplyPlugin and extended it a little bit:
sfGuardUserProfile:
actAs:
Timestampable: ~
columns:
user_id:
type: bigint(20)
notnull: true
default:
unsigned: false
primary: false
unique: false
autoincrement: false
email_new:
type: string(255)
unique: true
firstname:
type: string(255)
lastname:
type: string(255)
city:
type: varchar(255)
validate_at:
type: timestamp
validate:
type: string(33)
relations:
User:
class: sfGuardUser
foreign: id
local: user_id
type: one
onDelete: cascade
foreignType: one
foreignAlias: Profile
indexes:
validate:
fields: [validate]
Does anyone know how to fix this?
Thanks

user_id:
type: bigint(20)
ist not compatible to sfGuardUser
sfGuardUser:
type: integer()

In your fixtures for sfGuardUserProfile you need to specify the sfGuardUser link as you have a foreign link to it that cannot be null
sfGuardUserProfile:
bob_profile:
sfGuardUser: bob # Set the link
firstname: bob
# bobs_profile fixtures
sfGuardUser:
bob:
# bobs fixtures

Check User's id type.
It has to be the same as sfGuardUserProfile user_id is: bigint(20)

Ok, so I had to add interger(11) to all of the tables in sfDoctrineGuardPlugin. A bit hacky, but works now

Related

Does sfGuardUser table have a primary key?

I'm new to Symfony and Doctrine and am writing a web app. I added the sfDoctrineGuardPlugin to my project. When I open the schema.yml file for the plugin I see this:
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_guest:
type: boolean
default: 0
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
Permissions:
class: sfGuardPermission
local: user_id
foreign: permission_id
refClass: sfGuardUserPermission
foreignAlias: Users
Does this schema generate a table with a primary key (and if so, how do I access it)? I've looked online and most of the pages that cover the schema for sfGuardUser display an id column that is the primary key. What am I missing? Thanks.
Yes, it's id, accessed as sfGuardUser u --> u.id, as in...
$user = Doctrine::getTable('sfGuardUser')->findOneById(55);
or...
$q = Doctrine_Query::create()
->select('u.*')
->from('sfGuardUser u')
->where('u.id = ?', 55);
$q->execute();
I think somewhere in the Doctrine documentation it says that Doctrine auto-generates an "id" primary key if one isn't declared in the YAML file. It used to be declared explicity in the sfGuardPlugin schema but as of Symfony 1.4.8 (I think), it's just not written.
One thing to watch out for is that elsewhere in your schema, you need to make sure that you declare the same numeric type for the other end of the foreign key relationship or otherwise it'll throw an error. I think it's just type: integer that you need.
If no primary key is given, doctrine will create an id fieldwith type bigint and with a primary key.

one-to-many and saving records

I am creating a simple CMS and I have a set of templates, each template can have multiple blocks within them.
So I have a one-to-many relationship between the templates and blocks (1 template can have many blocks)
So, when I create a block, it has a drop down of the templates that I can associate the block to using sfDoctrineChoice widget.
In my BlockForm.class.php
new sfWidgetFormDoctrineChoice(array('model' => 'Template', 'multiple'=>true, 'expanded'=>false))
My schema is:
Template:
actAs:
Timestampable: ~
columns:
name:
type: varchar(255)
layout:
type: text
relations:
Block:
class: Block
local: id
foreign: template_id
type: many
foreignType: one
alias: Block
foreignAlias: Template
Block:
columns:
template_id: { type: integer(8), notnull: true }
content: { type: clob, notnull: true }
The problem comes when I try to save the choices. It gives me a:
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens when I select 2 or more templates or when I select 1 option:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (db.block, CONSTRAINTblock_template_id_template_idFOREIGN KEY (template_id) REFERENCEStemplate(id))
Is my schema correct to do what I'm looking to do?
Thanks
Build the database tables the way you want them first.
Rename your old schema.yml to schema-20110610.yml
Run task symfony doctrine:build-schema
Take a look at the new schema.yml file you created. It may give you an idea of what you are doing wrong...
You must add foreign key constraint. onDelete and onUpdate.
Template:
actAs:
Timestampable: ~
columns:
name:
type: varchar(255)
layout:
type: text
Block:
columns:
template_id: { type: integer(8), notnull: true }
content: { type: clob, notnull: true }
relations:
Template:
local: template_id
foreign: id
foreignAlias: Blocks

In doctrine what implications do 'relations:' have if the 2 relations are defined for two seperate column with a same table?

Suppose I have defined VendorClientLicense model like this:
VendorClientLicense:
tableName: vendor_client_licenses
columns:
id:
type: integer(4)
primary: true
notnull: true
autoincrement: true
status:
type: string(255)
default: 'pending'
client_id:
type: integer(8)
notnull: true
vendor_id:
type: integer(8)
notnull: true
relations:
sfGuardUser:
class: sfGuardUser
local: client_id
foreign: id
foreignAlias: VendorClientLicenses
foreignType: many
owningSide: true
sfGuardUser:
class: sfGuardUser
local: vendor_id
foreign: id
foreignAlias: VendorClientLicenses
foreignType: many
owningSide: true
indexes:
fk_vendor_client_licenses_sf_guard_user1:
fields: [client_id]
fk_vendor_client_licenses_sf_guard_user2:
fields: [vendor_id]
options:
charset: utf8
collate: utf8_unicode_ci
If you see the two relations are defined with same name 'sfGuarduser'; What I have found for this in mysql is that in generated database client_id does not show any association with sfGuardUser, whereas vendor_id does! If I change it to 'sfGuardUser1' and 'sfGuardUser2' then shows both relationship! So I assume eventually this has important significance and should not be identical for a same model. Is there any other implications for it?
Plus can you name me a good schema generator like 'mysqlworkbenchdoctrineplugin' which handles situation like this automatically?
Yes, you need to name them differently.
I asked & received for the same problem here:
MySQL: Two foreign keys in one table referring to another table
I haven't had any problems with it.
Regarding the plugin, sorry can't help you.

How do I access the list of tags linked to a blog post?

I'm doing a blog engine using symfony as a learning exercice.
How do I get the list of tags from the id of a blog post ?
Here's the database shema :
I added the following in the model :
public static function getTags($id)
{
return Doctrine_Core::getTable('Tag')
->createQuery('t')
->select('t.name, t.slug')
->leftJoin('t.ContentTag ct')
->where('ct.content_id = ?', $id)
->orderBy('t.name ASC');
}
and here is part of the schema.yml :
Content:
connection: doctrine
tableName: ec_content
actAs:
Sluggable:
fields: [title]
unique: true
canUpdate: true
Timestampable:
columns:
id:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: true
(...)
relations:
Comment:
local: id
foreign: content_id
type: many
ContentTag:
local: id
foreign: content_id
type: many
ContentTag:
connection: doctrine
tableName: ec_content_tag
columns:
content_id:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
tag_id:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
relations:
Content:
local: content_id
foreign: id
type: one
Tag:
local: tag_id
foreign: id
type: one
It's difficult to tell without seeing exactly how your schema is defined (i.e. schema.yml), but my guess would be that this would work, assuming you have the content object loaded:
$tags = $content->Tags;
Otherwise, your code snippet should work, so far as I can tell. You just need to stick ->exec() on the end to make it return the results of the query rather than the query object itself:
return Doctrine_Core::getTable('Tag')
->createQuery('t')
->select('t.name, t.slug')
->leftJoin('t.ContentTag ct')
->where('ct.content_id = ?', $id)
->orderBy('t.name ASC')
->exec();
Edit Having seen your schema, it seems that you have not created a relationship between Content and Tags, which you need to do. You can let Doctrine handle their interaction. The Symfony and Doctrine book uses something essentially identical to your example to demonstrate how to do a many-to-many relationship. (Note that, although this document is for an out-of-date version of symfony, the syntax for this feature has not changed.)

How to export primary keys on data-dump?

When I export my database with doctrine:data-dump, I encounter 2 problems:
* the primary keys are not exported
* instead of foreign keys columns correct name, it uses the name of the foreign table.
For example, here are my tables:
# schema.yml
Planet:
connection: doctrine
tableName: planet
columns:
planet_id:
type: integer(4)
fixed: false
unsigned: false
primary: true
sequence: planet_planet_id
solarsystem_id:
type: integer(4)
fixed: false
unsigned: false
notnull: false
primary: false
# some columns...
relations:
Solarsystem:
local: solarsystem_id
foreign: solarsystem_id
type: one
# other relations...
Solarsystem:
connection: doctrine
tableName: solarsystem
columns:
solarsystem_id:
type: integer(4)
fixed: false
unsigned: false
primary: true
sequence: solarsystem_solarsystem_id
# other columns...
relations:
Planet:
local: solarsystem_id
foreign: solarsystem_id
type: many
# other relations
When I dump, I find things like that in data.yml:
Planet_1:
Solarsystem: _1
When I data-load that, it doesn't work (Invalid row key specified: (solarsystem) _1, referred to in (planet) Planet_1). I have to fix manually like this:
Planet_1:
solarsystem_id: 1
planet_id: 1
For the moment, I'm fixing the data.yml manually, but it begins to become a pain with all the records I'm accumulating...
Note: I'm using Symfony 1.4, Doctrine, postgreSQL, NetBeans, Windows. Feel free to ask information you would judge useful.
Thanks for your help
I recommend checking out this article entitled "Never Trust doctrine:data-dump": http://www.thomaskeller.biz/blog/2010/01/29/never-trust-doctrinedata-dump/
With that in mind, you may instead prefer checking out pg_dump:
http://www.postgresql.org/docs/8.1/static/backup.html#BACKUP-DUMP
This dump is postgreSQL level, and as such is not likely to care about -- or stumble over -- your Doctrine schema.

Resources