Yii Framework Forum: Restfullyii Custom Attributes - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Restfullyii Custom Attributes How to get specific attributes in JSON? Rate Topic: -----

#1 User is offline   Paul Stiefel 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 15-March 13

Posted 23 November 2013 - 08:14 AM

Hi there,

I'm setting up an application using a REST api. Instead of writing one my own, the RestfullYii extension looks quite promising to use! Supports all kind of functionality "out of the box".

What I'm struggling with, is how to select specific attributes from my model for output to JSON? There are the model.visible.properties and model.hidden.properties events, but these seem only to work with the default
$model->attributes
collection. These attributes are really only the columns of the underlying table, so what if I want to output
$model->myCustomAttribute
optionally via
$model->getMyCustomAttribute()
as well?
1

#2 User is offline   daniel.fiechter 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 8
  • Joined: 16-July 12

Posted 25 November 2013 - 11:25 AM

We're struggling with the same issue. We declared our attribute explicit in the model as a class variable
public $fullname

and we added a "safe" rule
array('fullname', 'safe')


but unfortunately neither works.

I assume that the Restfullyii only looks up the database structure and not the model itself.

Has anyone an idea how to solve this?
0

#3 User is offline   Paul Stiefel 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 15-March 13

Posted 25 November 2013 - 12:23 PM

I hoped this might be solved by using a behavior, but as far as I can see it is not possible to overrule the getAttributes() method with it. So only possibility looks like overriding getAttributes() in the model itself, which looks like an ugly solution.

Perhaps this is a more generic issue, concerning customization of getAttributes()? I can imagine that abstraction of a database via models requires one to be able exactly which attributes are exposed?
0

#4 User is offline   Paul Stiefel 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 15-March 13

Posted 27 November 2013 - 03:53 PM

Anyhow, for those interested, it is possible to choose which attributes to get from your model via explicitly passing $names (array of attribute names you need) in $model->getAttributes($names).

In the RestfullYii extension there is the widget ERestJSONOutputWidget, in which there is a function that extracts the attributes from the model to process them to JSON, but there is no option to choose which attributes:

public function processAttributes($model, $relation = null)
    {
        $model_as_array = [];
        foreach ($model->attributes as $property => $value) {
            if (!$this->propertyIsVisable($property, $relation)) {
                continue;
            }
            $model_as_array[$property] = $value;
        }
        return $model_as_array;
    }


My personal conclusion:
1) It would be nice to be able to set some property in a CActiveRecord model with an array of default attributes that is used by getAttributes() and setAttributes().
2) It would be nice to have some way to choose in the RestfullYii extension which attributes you want to output.

In the meantime, I'm making a workaround that adds 1) to my CActiveRecord models.
0

#5 User is offline   daniel.fiechter 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 8
  • Joined: 16-July 12

Posted 04 December 2013 - 07:59 AM

We came up with the following solution:
Since all of our models inherit from a TwActiveRecord (which itself inherits from CActiveRecord), we added a new method "getAttributes" to TwActiveRecord
public function getAttributes($names=true)
{
    $attributes = parent::getAttributes($names);

    foreach ($this->getSafeAttributeNames() as $attribute) {
        if (!array_key_exists($attribute, $attributes))
            $attributes[$attribute] = $this->$attribute;
    }

    return $attributes;
}


So we now only need to specify our virtual attributes in the safe array of the model rules.
I am not sure if this comes with good performance or if there is another way to get (only) virtual attributes. But so far it is a working solution...
0

#6 User is offline   daniel.fiechter 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 8
  • Joined: 16-July 12

Posted 11 January 2014 - 03:46 AM

Now we have the next problem:
We wrote a setter for a virtual attribute
public function setHardwareCost($value)
. But when we try to update a model (PUT request), we get the following error:
{
  "success": false,
  "message": "Parameter 'hardwareCost' is not allowed for model (HardwareType)",
  "data": {
    "errorCode": 406,
    "message": "Parameter 'hardwareCost' is not allowed for model (HardwareType)"
  }
}


Is there a similar approach to overwrite the "safeAttributes"? We tried by extending the getSafeAttributes Method in our model, but this didn't work...
0

#7 User is offline   tavangar79 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 27-January 14

Posted 13 April 2014 - 02:37 PM

for do it you cat see my sample
i have some field
{"success":true,"message":"Record Found","data":{"totalCount":1,"messages":{"id":"1","text":"sfsdfsdafasdfsdaf","categories":"1,2,3,5","likecount":"50","reportcount":"0","delete":null,"date":null,"userid":"1","comments":[],"likes":[],"messageCategories":[{"id":"1","message_id":"1","category_id":"1"},{"id":"2","message_id":"1","category_id":"2"},{"id":"3","message_id":"1","category_id":"5"}],"user":{"id":"1","username":"test","password":"123","name":"m","email":"t","email_confirmed":"1","phone":"45465","phone_confirmed":"1","reported_count":"0","profile_picture":null,"cover_picture":null,"created_time":null,"last_visit_time":null,"last_login_time":null,"last_logout_time":null,"deleted":null,"block_start_time":null,"blocked":null}}}}


and i want to dont show user password and i add this code to my controller

public function restEvents() {
        $this->onRest('req.auth.ajax.user', function() {
                    return true;
                });
        $this->onRest('model.visible.properties', function() {
                    return ['user.name'];
                });
    }


you can use model.hidden.properties too
0

Share this topic:


Page 1 of 1
  • 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