Improvement on models
#1
Posted 11 May 2009 - 08:04 PM
We may follow Jonah's idea about merging rules() and safeAttributes(): if an attribute is listed in a rule (for the given scenario), it is considered to be safe.
We'd like to hear your opinions and suggestions. In particular, if we choose to merge them, how should the merged method look like?
#2
Posted 11 May 2009 - 11:01 PM
By Jonah's idea Yii will be forcing using safe attributes and I don't appreciate them very much.
#3
Posted 12 May 2009 - 01:25 AM
but I guess that's irrelevant...
&rickgrana has a point, every once in a while it would force you to write out a safe attribute rule if you use my method (if you want an attribute to be mass-assignable to the model but is not considered "required" - in my experience this is not very often) even if you don't care if your app is safe
#4
Posted 12 May 2009 - 06:59 AM
Ej.:
<?php
public function rules()
{
return array(
array('someAttribute1','length','max'=>50),
array('someAttribute2','length','max'=>255),
array('someAttribute1', 'required'),
array('someAttribute3,'numerical','integerOnly'=>true),
array('someAttribute1', 'someAttribute2', 'safe'),
);
}
If somebody gives me a good example of combine attributeLabels() with rules(), then i'll consider this alternative, but for now, I love attributeLabels().
#5
Posted 12 May 2009 - 07:21 AM
Currently I am creating something I call "field definition" - it is a simple class, containing everything a field must know about itself - label, default validators, field name in the database, friendly field name in the model etc. (I am still working on how to add scenarios correctly).
My idea was that fields are actualy repeating through the projects and even in the models - I mean - If in one model have field "name" or "email", it will be pretty same in another model/project. The only thing that strongly differentiates them is the scenarios they are used in...
I am still working on this "microarchitecture", but I finish it I will be able to reuse my field between models and projects, just mentioning the class.
#6
Posted 12 May 2009 - 07:53 AM
But, if you merge the methods, Yii wiil have backward compability for our attributesLabels and safeAttributes methods?
#7
Posted 12 May 2009 - 03:29 PM
That sounds just like what I was brainstorming the other day:
http://www.yiiframew...83.html#msg5083
#8
Posted 13 May 2009 - 01:24 AM
Quote
That sounds just like what I was brainstorming the other day:
http://www.yiiframew...83.html#msg5083
yes, yes!!
I didn't knew that this thread is there!!
You were right that attributes should be stored in one direcotry and just assigned to the models. That way they can be easilly reused... I call it "attributes repository" and I use a class - factory to create and assign them... (and I have a lot of work on this...
#9
Posted 13 May 2009 - 06:32 AM
From my point of view, usually, when I define rule for attribute it is safe.
I do not like mixing labels with rules, they are something different. Second reason is that split into more methods increase code readability. I know (with a one look) what is what.
#10
Posted 14 May 2009 - 02:18 AM
I vote to combine this into a single call. (Perhaps you would want specific labels for a scenario so that should be added to the map also. )
But if this is the case then it would also be nice to have "scenario merging" and "role based scenarios" also.
"scenario merging" : Be able to define a default scenario which is applied to all the other scenario's. This should allow you (for example) to define an attribute label for every other scenario if you dont need to change it.
"role based scenarios" : Be able to define and redefine a scenario that may be modified based on the users role. This should simplify the work of a controller in assigning a specific scenario based on a users role.
So the map would be
"<scenario>:<role>=>array("attributes"=>array(),"rules"=>array(), "safeAttributes"=>array())"
Where "<scenario>" may be blank (meaning applied to all scenarios)
and "<role>" may be * all users, ? guest users , "rolename"
So you could do
return array(
// Any user
":*"=>array("attributes"=>array("name"=>"Label"),
"rule"=>array(rules for all users),
"safe"=>array(safe for all usrs)),
"submit:admin"=>array("attributes"=>array("name"=>"Admin Label"),
"rules"=>array(rules for admin users),
"safeAttributes"=>array(safe for admin usrs)),
)...
I do like the ideas behind an attribute class but i think that would only take you part of the way..
Just some thoughts @3 in the morning..
nz
#11
Posted 14 May 2009 - 04:47 AM
If all there are merged, it could look something like this:
function attributes() {
array(
'name' =>
array('rules' =>
... bunch of rules ...
array('label' => 'Name',
array('safe') => true'),... which is OK (a bit like the configuration file), but is it simple enough for people to learn ?
#12
Posted 15 May 2009 - 06:40 AM
It would make form generation a piece of cake.
For the model I'd move the 'safe' attribute to the rules() method (or rename rules() to properties(). The attributeLabels I'm indifferent over.
It's a pity the php folks didn't add the alternate $array=[1=>'a',2=>'b'] syntax, it would have made stuff clearer.
#13
Posted 15 May 2009 - 10:16 AM
#14
Posted 15 May 2009 - 11:49 AM
Say you are retrieving 20 objects from a DB, and each object has 3 attributes as classes (not all the attributes necessarily need to be classes), that instantiating 60 objects in all.
Doesn't this already happen when you have many behaviors attached? I don't think the performance effect will be much different from the behavior feature. In fact, as the way I am looking at it, attributes as classes is not all that much different from behaviors (of course there are some key differences though).
Perhaps a model should be benchmarked with 5 or so behaviors attached, and if that's ok, I think attributes as classes should be ok
If this is implanted I highly recommend django's documentation on their implementation should be carefully read first, as they have some very good ideas that should be borrowed.
Of course djando is Python and not PHP, so just because it works for them does not necessarily mean it would work well for a PHP framework
#15
Posted 15 May 2009 - 11:55 AM
#16
Posted 15 May 2009 - 01:16 PM
But I would prefer having a separate function for labels so i can return a different array based on language
#17
Posted 15 May 2009 - 04:37 PM
Could ActiveRecord perhaps be designed in such a way that it would be possible to extend it to have such attributes ? Just thinking out loud. People could create their own or CFancyRecord would be shipped along with Yii
#18
Posted 15 May 2009 - 06:09 PM
only attributes that are defined as classes would behave as so I believe (thus backwards compatibility most likely).
#19
Posted 16 May 2009 - 04:37 AM
#20
Posted 16 May 2009 - 10:49 AM
Have a look at the official documentation. It suggests not to add fields like 'permission' to safeAttributes, since that would be make it possible to massively assign its value.
I don't want my site to be hacked via a simple form just by adding a new field permission=admin.
Or, after merging the two (or three) methods, will it be still possible not to allow certain properties to be massively assigned?

Help
















