Yii Framework Forum: Changes and new features for CModel - Yii Framework Forum

Jump to content

  • (3 Pages)
  • +
  • 1
  • 2
  • 3
  • You cannot start a new topic
  • You cannot reply to this topic

Changes and new features for CModel

#1 User is offline   qiang 

  • Yii Project Lead
  • Yii
  • Group: Yii Dev Team
  • Posts: 5,875
  • Joined: 04-October 08
  • Location:DC, USA

Posted 21 July 2011 - 10:12 AM

Do you have any major changes or feature requests for CModel and CFormModel? Please discuss in this thread. Thanks.
0

#2 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,448
  • Joined: 04-October 10

Posted 22 July 2011 - 06:19 PM

Would be nice to have certain methods like:

- toArray();
- toJSON();
¿How long would it take for you to understand that you own nothing in this world?

www.ramirezcobos.com
www.2amigos.us
www.github.com/tonydspaniard
www.github.com/2amigos


Posted Image
0

#3 User is offline   qiang 

  • Yii Project Lead
  • Yii
  • Group: Yii Dev Team
  • Posts: 5,875
  • Joined: 04-October 08
  • Location:DC, USA

Posted 22 July 2011 - 07:29 PM

Let's discuss AR in a different thread. In this thread, we focus on the base model class. This is important because the base model serves as the common ground for other concrete model classes such as AR.

How are you going to use .toJSON()? What is the difference between .attributes and .toArray()?
0

#4 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,448
  • Joined: 04-October 10

Posted 23 July 2011 - 01:28 AM

The differences are that attributes its just about the fields of the table the model belongs to and both methods .toJSON and .toArray could also return the related models attributes in the requested format.

How I am going to use .toJSON? To have a client representation of the model and its relations to power my client JavaScript UI Elements.

For example, instead of loading a table with my AJAX call -CGridView paging, delete or update call, I just get a JSON or array representation and then update my UI elements, so to speed up the server execution time and allow the creation of more powerful and richer elements on the client.

If you look for example a ExtJS javascript library, you find out how client elements do automatically update themselves by JSON/Array responses from the server.

Edit: I imagine a future where a proper JQuery UI client library 'plugs' seamlessly into Yii allowing programmers to decide where to place the creation of its elements, Zii for server, Jii on the client? With dialogs, sliders, grids, tabs, etc, that communicate with Yii as easy as Yii does its things on the server side.
¿How long would it take for you to understand that you own nothing in this world?

www.ramirezcobos.com
www.2amigos.us
www.github.com/tonydspaniard
www.github.com/2amigos


Posted Image
0

#5 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,448
  • Joined: 04-October 10

Posted 23 July 2011 - 02:00 PM

Another way is that the model could be initialized from JSON

   // call to external URL that returns JSON object with attributes and relation objects
   $json = EHttp::getUrl('http://www.external.com/getCountry?id=2');

   $model = new Country();
   $model->fromJSON($json);

   // now model has been initialized from JSON object
   // we can now display it on the view

¿How long would it take for you to understand that you own nothing in this world?

www.ramirezcobos.com
www.2amigos.us
www.github.com/tonydspaniard
www.github.com/2amigos


Posted Image
1

#6 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,350
  • Joined: 17-January 09
  • Location:Russia

Posted 23 July 2011 - 02:35 PM

Antonio Ramirez
1. Why moving JSON encoding into model?
2. How not to encode some properties?
3. How to specify if we need to encode related models or not?
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

#7 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,448
  • Joined: 04-October 10

Posted 23 July 2011 - 03:23 PM

1. Why moving JSON encoding into model?

To have a client representation of the model and its relations to power my JavaScript UI Elements, and possibly model information server exchange

2. How not to encode some properties?
3. How to specify if we need to encode related models or not?

This one is harder to answer, maybe through a flag on the methods
   return $model->toJSON(array('attributes'=>array('id'=>false),'relations'=>array('country'=>false)));

¿How long would it take for you to understand that you own nothing in this world?

www.ramirezcobos.com
www.2amigos.us
www.github.com/tonydspaniard
www.github.com/2amigos


Posted Image
0

#8 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,350
  • Joined: 17-January 09
  • Location:Russia

Posted 23 July 2011 - 06:28 PM

1. I understand the purpose of an encoding itself. But why can't we add related models handling to the current CJSON::encode? Why making encoding a part of the model?
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

#9 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,448
  • Joined: 04-October 10

Posted 24 July 2011 - 03:49 AM

View Postsamdark, on 23 July 2011 - 06:28 PM, said:

1. I understand the purpose of an encoding itself. But why can't we add related models handling to the current CJSON::encode? Why making encoding a part of the model?


Both ways are acceptable... didn't think about improving CJSON
¿How long would it take for you to understand that you own nothing in this world?

www.ramirezcobos.com
www.2amigos.us
www.github.com/tonydspaniard
www.github.com/2amigos


Posted Image
0

#10 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,350
  • Joined: 17-January 09
  • Location:Russia

Posted 24 July 2011 - 06:26 AM

I think keeping JSON-related things in JSON class is better since after adding JSON I'll need converting to XML etc.

Again, about the topic. It's about CModel and CFormModel. So:

— attributes.
— errors.
— scenario.
— validators.
— events.
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

#11 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 24 July 2011 - 09:54 AM

to get an instance of the class, the declaration of the method 'model' will not be needed anymore in child classes, and can be simplfied in CModel like
public static function model(){
   $modelClass=get_called_class();
   //same old logic
}

calling myModel::someMethod will now be possible with get_called_class and __callStatic, the implementation can be something like
public static function __callStatic($method,$args){
	return call_user_func_array(array(self::model(),$method),$args);
}
//usage
MyModel::setAttributes($_POST['MyModel'])->validate();
MyModel::findAll();


what do you think ?
--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#12 User is offline   qiang 

  • Yii Project Lead
  • Yii
  • Group: Yii Dev Team
  • Posts: 5,875
  • Joined: 04-October 08
  • Location:DC, USA

Posted 24 July 2011 - 10:00 AM

This should be better discussed in CActiveRecord thread, as this thread is about the base model.

The declaration of the model() method is no longer needed, using PHP 5.3.
However, we probably will still use something like this to do query:
Post::model()->findAll().

The main reason is that we need a place to store the query criteria so that you can modify it using scopes, etc.
We may seek for a pattern to separate the finder class and the object storage class, though. Not decided yet.
0

#13 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 24 July 2011 - 10:22 AM

Quote

This should be better discussed in CActiveRecord thread, as this thread is about the base model.

I am actually refering to CModel, findAll is just an example of a very common usage of CModel + AR, my other example is still valid
CModel::setAttributes($attributes)->validate()

that refers to CModel in general, including CFormModel and AR

Quote

The main reason is that we need a place to store the query criteria so that you can modify it using scopes, etc.

actually, by declaring __callStatic like I just posted, will do that, as it calls self::model() in __callStatic, returning an instance of the model

What you can do is
$model=MyFormModel::setScenario('create')->setAttributes($_POST);
if($model->validate()){
   echo 'works!!';
}

1 change needed to perform the code above is that setter methods needs to return $this;

this change may cause confusion at first, but will simplify things ,9 less chars to write, 'model()->' , a lot of times

as for the others functions of CModel, like samdark wrote

Quote

— attributes.
— errors.
— scenario.
— validators.
— events.


I'm very happy with the way it works now
--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#14 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,350
  • Joined: 17-January 09
  • Location:Russia

Posted 24 July 2011 - 01:36 PM

I think we shouldn't mix object and finder methods like $model=MyFormModel::setScenario('create')->setAttributes($_POST). This looks too magical. $model = new MyFormModel(); is much more explicit.

btw., the fact that scopes are currently applied to all model objects instead of specific one confuses developers a lot.
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

#15 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 25 July 2011 - 01:59 AM

Not sure, if this is also more related to AR only, but maybe it still makes sense in CModel:

I want automatic handling of localized formats for dates and numbers (both for displaying and parsing formatted values).

I would suggest, that for any attribute of <name> there should be an implicit attribute formatted<name>. This virtual attribute would be used as attribute name in forms:

<?php 
// Input for 'amount':
$form->textField($model,'formattedAmount');


It would handle formatting and parsing of localized numbers and dates. The model should parse formattedAmount into amount onBeforeValidate and, in case of an error, add errors to both, amount and formattedAmount. The formats should be configurable per attribute, scenario and target language in the model. We could have a method formats() that works similar to rules() but returns a number/date format for an attribute.

For AR some of this could be automated, as we know if something is a number or a date. We could have a global default format for numbers and dates.

I was thinking about implementing a behavior for this. But for full I18N support, something like this should be supported by the core.
0

#16 User is offline   Ben 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 266
  • Joined: 15-March 09

Posted 25 July 2011 - 03:25 AM

Ah, prefixes. Could models - especially FormModels - also handle data types?

// in some controller
$model = new LoginForm();
if (isset($_POST['LoginForm']))
{
  $model->attributes = $_POST['LoginForm'];

  //
  // now, here all the attributes should have been converted into the correct datatype  
  //
}

// variant 1 - using prefixes
class LoginForm extends FormModel
{
  public $strUser = '';
  public $strPswd = '';
  public $bAutoLogin = false;
  public $iSessionTimeout = 60*60;
}

// variant 2 - using doc comments
class LoginForm extends FormModel
{
  /**
   * @var string
   */
  public $user = '';

  /**
   * @var string
   */
  public $pswd = '';

  /**
   * @var bool
   */
  public $autoLogin = false;

  /**
   * @var integer
   */
  public $sessionTimeout = 60*60;
}


Don't like ads in my sig...
0

#17 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,350
  • Joined: 17-January 09
  • Location:Russia

Posted 25 July 2011 - 05:54 AM

Mike
Formatting is a part of the view layer. Any practical example where your way is better than just calling appropriate formatter in the view?

Ben
Aren't they converted if proper rules such as boolean are used?
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

#18 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 25 July 2011 - 05:59 AM

View Postsamdark, on 25 July 2011 - 05:54 AM, said:

Mike
Formatting is a part of the view layer. Any practical example where your way is better than just calling appropriate formatter in the view?


It's also about parsing these values back into DB format. So it's a simple automatism for back and forth conversion. We also have other view related properties in the model, e.g. labels or error messages.

The only workaround for now is to write custom getters/setters for each number/date column. This is very repetitive as it's most often using the same formatting schema. Having support for this would make localization much less cumbersome when it comes to dates and numbers.
0

#19 User is offline   Ben 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 266
  • Joined: 15-March 09

Posted 25 July 2011 - 04:34 PM

View Postsamdark, on 25 July 2011 - 05:54 AM, said:

Ben
Aren't they converted if proper rules such as boolean are used?


Is this a trick question? Is there a way to make it work? :unsure:

Hm... Here's what I'm trying to do and the results:


// --- Model -----------------------------

class LoginForm extends CFormModel
{
  public $username='';
  public $password='';
  public $rememberMe=true;
  public $sessionTimeout=3600;

  public function rules()
  {
    return array(
      array('username, password', 'required'),
      array('rememberMe', 'boolean'),
      array('sessionTimeout', 'numerical', 'integerOnly' => true),
      array('password', 'authenticate'),
    );
  }
}

// --- in Controller -----------------------------

public function actionLogin()
{
  $model=new LoginForm;

  if(isset($_POST['LoginForm']))
  {
    CVarDumper::dump( $_POST['LoginForm'], 3, true );
    // array
    // (
    //     'username' => 'demo'
    //     'password' => 'demo'
    //     'rememberMe' => '1'
    //     'sessionTimeout' => '3600'
    // )

    // I like type safety. So ideally, conversion should happen on assignment
    $model->attributes = $_POST['LoginForm'];
    CVarDumper::dump( $model, 3, true );
    // LoginForm#1
    // (
    //     [username] => 'demo'
    //     [password] => 'demo'
    //     [rememberMe] => '1'
    //     [sessionTimeout] => '3600'
    //     ...
    // )

    // Up to now, the model still holds string data. Maybe after validation...
    $model->validate();
    CVarDumper::dump( $model, 3, true );
    // LoginForm#1
    // (
    //     [username] => 'demo'
    //     [password] => 'demo'
    //     [rememberMe] => '1'
    //     [sessionTimeout] => '3600'
    //     ...
    // )

    [...]
  }
}



What I liked the data to be is (at least after validation):

// LoginForm#1
// (
//     [username] => 'demo'
//     [password] => 'demo'
//     [rememberMe] => true
//     [sessionTimeout] => 3600
//     ...
// )



///////////////////
// EDIT:
Using validation rules for type conversion instead of prefixes or doc comments looks like a good idea to me.
Don't like ads in my sig...
0

#20 User is offline   samdark 

  • Having fun
  • Yii
  • Group: Yii Dev Team
  • Posts: 3,350
  • Joined: 17-January 09
  • Location:Russia

Posted 25 July 2011 - 05:57 PM

Ben
It doesn't produce true because http://www.yiiframew...rueValue-detail is 1 by default. That's to be able to write value into DB but you can change it if needed. You're right about numerical validator. It doesn't convert value into integer. Conversion via validators looks like a good idea.
Yii 1.1 Application Development Cookbook

Enjoying Yii? Star us at github: 1.1 and 2.0.
0

Share this topic:


  • (3 Pages)
  • +
  • 1
  • 2
  • 3
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users