Doktrin 2'de nasıl varsayılan bir değer ayarlayabilirim?
Doktrin 2'de nasıl varsayılan bir değer ayarlayabilirim?
Yanıtlar:
Veritabanı varsayılan değerleri "taşınabilir" olarak desteklenmez. Veritabanı varsayılan değerlerini kullanmanın tek yolu , alanın eşlendiği sütun için snippet'i ( neden dahil) columnDefinition
belirttiğiniz eşleme özniteliğidir .SQL
DEFAULT
Kullanabilirsiniz:
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @Column(name="myColumn", type="string", length="50")
*/
private $myColumn = 'myDefaultValue';
...
}
PHP düzeyinde varsayılan değerler tercih edilir, çünkü bunlar yeni oluşturulan ve kalıcı nesnelerde de uygun şekilde bulunur (Doktrin, varsayılan değerleri almak için yeni bir nesneye devam ettikten sonra veritabanına geri dönmez).
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @ORM\Column(name="myColumn", type="integer", options={"default" : 0})
*/
private $myColumn;
...
}
Bunun, ve DEFAULT
gibi bazı alanlar için desteklenmeyen SQL kullandığını unutmayın .BLOB
TEXT
options={"default": 0}
Doktrin versiyonumda hatalara neden olduğu için "değil" i kullanmaya dikkat edin.
Varlığınızda bir kurucu ayarlayın ve orada varsayılan değeri ayarlayın.
kullanın:
options={"default":"foo bar"}
ve yok:
options={"default"="foo bar"}
Örneğin:
/**
* @ORM\Column(name="foo", type="smallint", options={"default":0})
*/
private $foo
Symfony belgelerini okumanın bir nedeni daha trend dışı kalmayacak. Özel durumum için basit bir çözüm var ve field type
seçeneği empty_data
varsayılan bir değere ayarlamaktır.
Yine, bu çözüm yalnızca bir formdaki boş bir girdinin DB alanını null olarak ayarladığı senaryo içindir.
Önceki cevapların hiçbiri özel senaryomda bana yardımcı olmadı ama bir çözüm buldum.
Aşağıdaki gibi davranması gereken bir form alanı vardı:
Daha sonra burada verilen tüm önerileri denedim. Onları listeleyeyim:
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @Column(name="myColumn", type="string", length="50")
*/
private $myColumn = 'myDefaultValue';
...
}
@ORM\Column(name="foo", options={"default":"foo bar"})
/**
* @Entity
*/
class myEntity {
...
public function __construct()
{
$this->myColumn = 'myDefaultValue';
}
...
}
Hiçbiri işe yaramadı ve hepsi Symfony'un Entity sınıfınızı nasıl kullandığından dolayı.
Symfony form alanları, Entity sınıfında ayarlanan varsayılan değerleri geçersiz kılar.
Yani, DB'niz için şemanızın varsayılan bir değeri tanımlanmış olabilir, ancak formunuzu gönderirken zorunlu olmayan bir alanı boş bırakırsanız form->handleRequest()
, form->isValid()
yönteminizin içi Entity
sınıfınızdaki bu varsayılan değerleri geçersiz kılar ve bunları giriş alanı değerlerine ayarlar. Giriş alanı değerleri boşsa, Entity
özelliği olarak ayarlar null
.
http://symfony.com/doc/current/book/forms.html#handling-form-submissions
Yöntemin form->handleRequest()
içinde sonra denetleyicinizdeki varsayılan değeri ayarlayın form->isValid()
:
...
if ($myEntity->getMyColumn() === null) {
$myEntity->setMyColumn('myDefaultValue');
}
...
Güzel bir çözüm değil ama işe yarıyor. Muhtemelen bir yapabilirim, validation group
ancak bu sorunu veri doğrulaması yerine bir veri dönüşümü olarak gören insanlar olabilir , karar vermek için size bırakıyorum.
Ayrıca Entity
ayarlayıcıyı bu şekilde geçersiz kılmaya çalıştım :
...
/**
* Set myColumn
*
* @param string $myColumn
*
* @return myEntity
*/
public function setMyColumn($myColumn)
{
$this->myColumn = ($myColumn === null || $myColumn === '') ? 'myDefaultValue' : $myColumn;
return $this;
}
...
Bu, daha temiz görünse de, işe yaramıyor . Bunun nedeni, kötü form->handleRequest()
yöntemin, verileri güncellemek için Model'in ayarlayıcı yöntemlerini kullanmamasıdır ( form->setData()
daha fazla ayrıntı için içeri girin ).
Kullandığım geçici çözüm bir LifeCycleCallback
. Örneğin, daha fazla "yerel" yöntem olup olmadığını görmek için hala bekliyor@Column(type="string", default="hello default value")
.
/**
* @Entity @Table(name="posts") @HasLifeCycleCallbacks
*/
class Post implements Node, \Zend_Acl_Resource_Interface {
...
/**
* @PrePersist
*/
function onPrePersist() {
// set default date
$this->dtPosted = date('Y-m-d H:m:s');
}
if (!$this->getDtPosted()) { $this->setDtPosted(new \DateTime()); }
Bunu xml kullanarak da yapabilirsiniz:
<field name="acmeOne" type="string" column="acmeOne" length="36">
<options>
<option name="comment">Your SQL field comment goes here.</option>
<option name="default">Default Value</option>
</options>
</field>
İşte bunu kendim için çözdüm. Aşağıda, MySQL için varsayılan değeri olan bir Varlık örneği verilmiştir. Bununla birlikte, bu ayrıca varlığınızda bir kurucu kurulumu gerektirir ve orada varsayılan değeri ayarlamanız gerekir.
Entity\Example:
type: entity
table: example
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
label:
type: string
columnDefinition: varchar(255) NOT NULL DEFAULT 'default_value' COMMENT 'This is column comment'
columnDefinition
doğrudan veritabanından soyut olan bir ORM'ye sahip olma amacına yöneliktir. Bu çözüm taşınabilirliği bozacak, yazılımınızı DB satıcınıza bağlı tutacak ve Doktrin Geçiş araçlarını da bozacaktır.
Benim için de bir mysql veritabanı üzerinde çalışır:
Entity\Entity_name:
type: entity
table: table_name
fields:
field_name:
type: integer
nullable: true
options:
default: 1
Bunların hiçbiri benim için işe yaramadı. Doktrin sitesinde, varsayılan değeri ayarlamak için değeri doğrudan ayarlayan bazı belgeler buldum.
private $default = 0;
Bu istediğim değeri ekledi.
@Romanb pırıltılı cevaba ekleniyor.
Bu, taşıma işlemine biraz ek yük getirir, çünkü null kısıtlaması olmayan ve varsayılan değeri olmayan bir alan oluşturamazsınız.
// this up() migration is autogenerated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != "postgresql");
//lets add property without not null contraint
$this->addSql("ALTER TABLE tablename ADD property BOOLEAN");
//get the default value for property
$object = new Object();
$defaultValue = $menuItem->getProperty() ? "true":"false";
$this->addSql("UPDATE tablename SET property = {$defaultValue}");
//not you can add constraint
$this->addSql("ALTER TABLE tablename ALTER property SET NOT NULL");
Bu cevapla, neden ilk etapta veritabanında varsayılan değere ihtiyacınız olduğunu düşünmenizi öneririm. Ve genellikle, null kısıtlaması olmayan nesneler oluşturmaya izin vermektir.
Varlığınız için yaml tanımı kullanırsanız, postgresql veritabanında aşağıdakiler benim için çalışır:
Entity\Entity_name:
type: entity
table: table_name
fields:
field_name:
type: boolean
nullable: false
options:
default: false
$entity->setFieldName()
Yıkamadan önce kullanmadıysanız ne olacak ? Doktrin varsayılan değeri null olarak tanımlamaktadır. YAML tek çözüm varsayılan değeri tanımlamaktır İÇİNDE -_- ... zaten YAML tanımlanan beri bana aptal görünüyor varlık sınıfında
Aynı sorunla mücadele ettim. Ben veritabanından varlıklar (otomatik olarak) varsayılan değeri olmasını istedim. Bilin bakalım ne yaptım :)
<?php
/**
* Created by JetBrains PhpStorm.
* User: Steffen
* Date: 27-6-13
* Time: 15:36
* To change this template use File | Settings | File Templates.
*/
require_once 'bootstrap.php';
$em->getConfiguration()->setMetadataDriverImpl(
new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
$em->getConnection()->getSchemaManager()
)
);
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($em->getConnection()->getSchemaManager());
$driver->setNamespace('Models\\');
$em->getConfiguration()->setMetadataDriverImpl($driver);
$cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
$metadata = $cmf->getAllMetadata();
// Little hack to have default values for your entities...
foreach ($metadata as $k => $t)
{
foreach ($t->getFieldNames() as $fieldName)
{
$correctFieldName = \Doctrine\Common\Util\Inflector::tableize($fieldName);
$columns = $tan = $em->getConnection()->getSchemaManager()->listTableColumns($t->getTableName());
foreach ($columns as $column)
{
if ($column->getName() == $correctFieldName)
{
// We skip DateTime, because this needs to be a DateTime object.
if ($column->getType() != 'DateTime')
{
$metadata[$k]->fieldMappings[$fieldName]['default'] = $column->getDefault();
}
break;
}
}
}
}
// GENERATE PHP ENTITIES!
$entityGenerator = new \Doctrine\ORM\Tools\EntityGenerator();
$entityGenerator->setGenerateAnnotations(true);
$entityGenerator->setGenerateStubMethods(true);
$entityGenerator->setRegenerateEntityIfExists(true);
$entityGenerator->setUpdateEntityIfExists(false);
$entityGenerator->generate($metadata, __DIR__);
echo "Entities created";
Yapıcıdaki değeri ayarlamak işe yarayacak olsa da, Doktrin Yaşam Döngüsü olaylarını kullanmak daha iyi bir çözüm olabilir.
prePersist
Yaşam Döngüsü Etkinliğinden yararlanarak, varlığınızdaki varsayılan değerinizi yalnızca ilk kalıcı olarak ayarlayabilirsiniz.
hack
. Asla korsanlara güvenmeyin.
Özellik tanımında varsayılan değerleri ayarlarken dikkatli olun! Bunu problemsiz tutmak için yapıcıda yapın. Özellik tanımında tanımlarsanız, nesneyi veritabanında saklarsanız, kısmi bir yükleme yaparsanız, yüklenmeyen özellikler yine varsayılan değere sahip olacaktır. Nesneyi tekrar ısıtmak istiyorsanız bu tehlikelidir.