I want to use the default value if the column is null. For example:
Settings (Table):
id | website_id | column1 | column2
1 | 1 | null | null
Website.php:
<?php
namespace App\Models;
class Website extends Model
{
public function Setting(): HasOne
{
return $this->hasOne(IvendiFinanceCalculatorSetting::class)->withDefault([
'column1' => 'Default',
'column2' => 0,
The above is a hypothetical example, but you can see what I'm attempting to achieve. If I add a row to my table with a matching website id, but leave the other columns as null I want to return the defaults.
Currently if query the Website model with the settings relationship I get back the row but column1 and column2 is null rather than Default and 0.
dd(Website::query()->with('Setting')->find(1));
withDefault works when the relationship is null, not the field values. See Null Object Pattern for more information.
You might be better served by model events, specifically creating for when new IvendiFinanceCalculatorSetting records are inserted.
Then in the model's boot method or an observer class, you can set default setting values:
// IvendiFinanceCalculatorSettingObserver.php example
public function creating (IvendiFinanceCalculatorSetting $setting) {
$setting->setAttribute('column1', 'Default');
$setting->setAttribute('column2', 0);
}
Another approach is setting the default values directly in the model's attribute property:
/**
* The model's default values for attributes.
*
* #var array
*/
protected $attributes = [
'column1' => 'Default',
'column2' => 0
];
Related
Created a migration with a new field of jsonb type, not null and default value = []. (example of stored data: ["235", "214"]) and add a rule to model [['unique_users'], 'safe']
public function up()
{
$connection = Yii::$app->getDb();
$sql = 'ALTER TABLE offer ADD unique_users jsonb not null default \'[]\'';
$command = $connection->createCommand($sql, []);
$command->queryAll();
}
Result: Added a unique_users field with a default value [] to each row. jsonb_typeof(unique_users) returns an array type.
Created needed query for test
select jsonb_array_length(unique_users) from test where unique_users #> '"19"'::jsonb
Result from PgAdmin:
It seemed that everything was ready. But after saving a new record with Yii2, I received a query error:
ERROR: you can not get the length of a scalar
And I saw that another value was recorded in the field - ""
I was tryed to add the validation rule to Model: ['unique_users', 'default', 'value' => '[]'],.
Result:
...with the same problem of query - value is not an array. jsonb_typeof(unique_users) returns an string type.
How to insert empty array into jsonb column?
I think you're accidentally sending an empty string as the value for your unique_users field. If the value would be completely empty it should take the default DB value for the column. Please make sure the unique_users field is completely empty (null) when saving.
You can however also do this with a default value rule. This should do the trick:
['unique_users', 'default', 'value' => json_encode([])],
['unique_users', 'default', 'value' => []],
I have a table on Postgres that auto generates UUIDs, when I dd Customer::all(); on Laravel I get an array with "cs_id" => "d0402be5-e1ba-4cb2-a80c-5340b406e2c3" which is fine. When I loop or select one record with the only the cs_id the data it retuns 0,2,5 for the three records currently on the table which is incorrect data.
EDIT:
CREATE TABLE customers
(
cs_id character varying(255) NOT NULL DEFAULT gen_random_uuid(),
CONSTRAINT cs_customers_pkey PRIMARY KEY (cs_id),
}
On laravel
$customerData = Customer::where('cs_id','d0402be5-e1ba-4cb2-a80c-5340b406e2c3')->first();
dd($customerData['cs_id']);
For some reason Eloquent messes up there.
just add a getter and use it whenever you need the cs_id
public function getGuid()
{
return $this->attributes['cs_id'];
}
To use uuids auto-generated by the database, define your model as follows:
class Customer extends Model
{
// rename the id column (optional)
protected $primaryKey = 'cs_id';
// tell Eloquent that your id is not an integer
protected $keyType = 'string';
// do NOT set $incrementing to false
}
Then you can use all Eloquent's methods as you would with classic ids:
$customerData = Customer::findOrFail('d0402be5-e1ba-4cb2-a80c-5340b406e2c3');
Use Customer::findOrFail('d0402be5-e1ba-4cb2-a80c-5340b406e2c3');
to get the record matching that pk.
I'm assuming on top you have use App\Customer;
What's the proper way to implement default values for Eloquent models?
I've configured my database tables using Laravel's migrations. Some columns have default values specified. When using these tables in conjunction with Eloquent models, different things happen depending on the selected database driver:
In MySQL, when creating a new model and saving it, a DB row is inserted having the column's default value for every attribute that was not explicitly specified. This is what I would like to happen.
In Postgres and SQLite however, this is not the case. A PDOException is thrown:
[PDOException]
SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column
"some_column" violates not-null constraint
DETAIL: Failing row contains (1, 2, 3, 4, 5, 6, null, null, null, null, null, null, 7, 8, null, 9, null, null, 10, 11, 12, null).
It is clear to me that the column is not nullable and that null values are not accepted. I would expect however that the default value was inserted instead of an error being raised.
I would suggest that you create your own parent model that extends Eloquent directly, and have all of your models extend this custom parent.
In the custom parent, override the performInsert() method to remove null values just before inserting. Be sure to copy the entire method from the Eloquent source code so you don't lose any important steps in the process:
class MyModelParent extends Illuminate\Database\Eloquent\Model
{
/**
* Perform a model insert operation.
*
* #param \Illuminate\Database\Eloquent\Builder $query
* #return bool
*/
protected function performInsert(Builder $query)
{
if ($this->fireModelEvent('creating') === false) {
return false;
}
... // Be sure to copy all of it!
// This is the change you'll make. Before, it was just:
// $attributes = $this->attributes;
$attributes = array_filter($this->attributes, function($val){
return $val !== null;
});
... // Be sure to copy all of it!
return true;
}
}
performUpdate() should handle this issue fine, since it uses getDirty() to get the list of fields instead of accessing the property directly.
And while you're at it, you should consider submitting a patch to Laravel that would make the core Postgres-safe.
SQL NOT NULL Constraint
The NOT NULL constraint enforces a column to NOT accept NULL values.
you are adding a null value on NOT NULL column
it seems
http://www.w3schools.com/sql/sql_notnull.asp
In a form Viewhelper I have lots of numeric fields, which should be empty by default, not filled with '0' or '0.00'.
I need this, because there should be a different handling of the data in the saveAction, depending on left empty fields or filled in values (including 0).
For this reason I set the field properties in the database table to NULL by default, like:
CREATE TABLE IF NOT EXISTS `tx_myext_domain_model_result` (
mw double (10,2) DEFAULT NULL,
mw2 double (10,2) DEFAULT NULL,
....
);
TCA looks like this:
'mw' => array(
...
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'double2,null'
)
),
Also, in the Result model class, the corresponding properties are initialized with NULL;
/**
* mw
*
* #var float
*/
protected $mw = null;
I did this check to assure that NULL is handled over to the getter for empty form fields:
public function setMw($mw) {
if ($mw == NULL)
$this->mw = 999;
else
$this->mw = $mw;
}
This did what I excepted: The mw field DB was set to '999' for a empty form field.
But now, switched back to normal setter,
public function setMw($mw) {
$this->mw = $mw;
}
fields in the DB table are only left NULL when all other form fields are left empty, too. I.e. as soon as I enter a value in one of the form fields, all other empty form fields are set to '0' on save.
Adding null to the TCA eval field didn't do the trick, neither.
How can I change this behaviour? I'm using TYPO3 6.2.x
step 1: in initializeAction set null for the property
step 2: the idea with checking $mw is null is preaty good idea. TYPO3 not always do what you can assume using logical thinking :) So check if(is_null($mw)) $this->mw = null
this two things should do the trick
you can also set a default value in setter param
setMw($mw = null)
Suppose that i have a table 't' with fields 'id' int 11, 'name' varchar 50, and 'description' text. if the text is very large, and i am querying the database with 'description' and without 'description', will there be any difference?
and how to select only 'id' and 'name' in the Model that extends Zend_Db_Table_Abstract class?
In term of perfomances I can't really help, but it should not make a big difference.
For your question about how to select fields in a query look at the following
class Model_DbTable_T extends Zend_Db_Table_Abstract{
protected $_name = 't'; // this line is optionnal if your table has the same name as the class
public function fetchSomeFields(){
$query = $this->select()
->from($this,
array('id')); // you could also include the 'as' statement in the field name to make it look like 'id as otherName'
return $this->fetchAll($query);
}
}