AR default values

Currently, when creating a new AR instance, some of its attributes will be initialized with the default values specified in the corresponding DB table. For example, if we have a post table defined as:

CREATE TABLE post (…, status INTEGER DEFAULT 1,…),

and we create a post AR object with

$post=new Post;

The $post->status attribute will become 1 automatically.

This has the benefit that we don’t need to explicitly specify the default value for “status” in the Post class.

However, it also causes the problem as described in http://code.google.com/p/yii/issues/detail?id=1050

Moreover, some DBMS support default values using DB expressions that we cannot exploit in PHP.

So should we remove the support for automatically initializing AR attributes with their DB defaults? Doing so will definitely break backward compatibility.

Please cast your vote. Thanks.

Hello,

imho AR should be initialized with default attribute values from DB only if "isNewRecord".

Anyway… if you remove the support for default values, how would this be handled?

…maybe you could have something $post->loadDefaults()->status ::)

bye,

Giovanni.

I think there must be a solution without removing this feature from AR. For example search scenario sets default values to empty strings. Or adding optional $castDefaultValues to AR constructor. (not sure how logic that is, didn’t used the filtering and grid-stuff much)

I don’t know how it works, but wouldn’t it be possible to execute such a db expression and then use the returned value as default?

I vote yes for now - keep it. Good feature.

I do a lot of audit trail logging, and I know that something along these lines will work when setting defaults:

                $log->field=        $value;


                $log->timestamp= new CDbExpression('NOW()');

Will this work for you?

I should have also mentioned you can do this in your model class:





	public function rules()

	{

		return array(

			array('somefield', 'numerical'),

			array('fieldthatNeedsDefault', 'default', 'value' => 'Default Value', 'setOnEmpty' => true),

			array('someotherfield', 'required'),

			.......

		);

	}



I have not tried it myself, but I don’t see why we can’t combine this with CDbExpression like so :





	public function rules()

	{

		return array(

			array('somefield', 'numerical'),

			array('fieldthatNeedsDefault', 'default', 'value' => new CDbExpression('NOW()'), 'setOnEmpty' => true),

			array('someotherfield', 'required'),

			.......

		);

	}



In theory, this will set your model field to the CDbExpression only if another value was not given. I can vouch that it works with a plain value, and while I haven’t tested it with a CDbExpression, I don’t see why it would not work. It is at least worth a try. Just remember that you have to use validate() on your model to make the rules kick in, but after that you should be good to go!

I would be nice… well I think it should do.

And it would be another way of getting default value from DB.

IMO

The problem is only for the filtering where we use $model=new yourmodel("search");

So I’m thinking about NOT to use the default values for the “search” scenario

edit:

or to have a function like clear() that we can use, for example

$model=new yourmodel("search");

$model->clear();

I wasn’t even aware that AR does that :).

Using default values from DB feels obscure for me. I always assign default values in the model, as this is more transparent for me and gives a better understanding of what’s going on. As it doesn’t work for all DBMS anyway i consider this feature untrustworthy and would never rely on it. But some users might think that, and could report bugs if not all default values are used. We shouldn’t give “false reliability” ;)

On the other hand i guess, we could still assign default values in the model class and thus override the default values from DB. As long as this is guaranteed, it doesn’t matter for me.

Personally I find it more annoying than useful.

Whilst i’ve never taken advantage of having these defaults, I have often had to unset them which just creates more work.

What would be nice is if there are defaults in the database, that these get automagically created in the model if Gii is used to create it.

I am with mike :lol:

just make it simple. ;D

i think the poll title confusing ? yes to remove…

thanks for all your hardwork.

I agree on this…

on the poll question you ask if you want to keep it while in the post you ask if you want it to be removed, if I’m right ::)

bye,

Giovanni.

In my opinion, we could have some boolean attribute in the AR that would give the option between loading or not loading default values when creating a new record. Something like

public $loadDefaults = false;

The same for filtering in CGridView, if I want to turn default values on, I should put ‘loadDefaults’ => true in options

Not sure if it is possible or not, but i think that it would be very flexible

regards!

:)

Sorry for the confusion in the title.

I think we probably can remove this feature, and let the code generator to declare the initialization (as Orteko suggested).

The only drawback is breaking BC.

Maybe Gii (or a dedicated tool for the upgrade) could "scan" existing models and find out when problems can occur, and eventually update the model adding the default parameters as Orteko suggested.

bye,

Giovanni.

I think that the method to initialize should be in the core, it’s default implementation is to load the defaults from the db, and called automatically when the model is created, so BC is not a problem…

BUT, this method shoul be overwriten by the code generator in next version of yii (e.g.: 1.4 and +) for each model…

Yes that would be a fix for the (obviously) most common problem.

Or just


$model=new yourmodel("search", false);

false == don’t trigger loading defaults from db

But default values are part of table-scheme, so I think it fits well to AR. Anyone know how RoR handles it?

I don’t know how many guys don’t use gii/code-generation at all, but I’m one of them. I hope we can find better solution here instead of breaking BC.

The problem I see is it can’t be configured globally. Only per model. But still this would be an option since there are not many scenarios were one don’t want to have the default values.

i think set default value in model will be better~

I really like the idea of having Gii set the defaults at model generation.

Would be nice if you could combine that with a toggle to load the defaults or not - if Gii generated with defaults, then have gii generate the toggle set to false, otherwise let the default toggle setting be true (load defaults).

I agree with this.

Hi Liang… in Yii 1.1.3 was added a function for this… $model->unsetAttributes() http://www.yiiframework.com/doc/api/CModel#unsetAttributes