Here's my record (model is nearly identical):

namespace Craft;

class Recurly_PlanRecord extends BaseRecord

  public function getTableName()
    return 'recurly_plans';

  protected function defineAttributes()
    return array(
      'sortOrder'      => AttributeType::SortOrder,
      'code'           => AttributeType::String,
      'max'            => AttributeType::Number,
      'min'            => AttributeType::Number,
      'annual'         => AttributeType::Bool,
      'base_endpoints' => AttributeType::Number,
      'endpoint_code'  => AttributeType::String,
      'base_cost'      => array(
        'type'     => AttributeType::Number,
        'decimals' => 2,
      'endpoint_cost'  => array(
        'type'     => AttributeType::Number,
        'decimals' => 2,

In the DB, the column types seem to be set correctly based on this. What I can't figure out how to do, is actually get data back in the specified types, not just strings.

Here's me using it in a service:

$record = Recurly_PlanRecord::model()->find();
var_dump($record->attributes); // all strings :(
var_dump($record->base_cost); // string '1402.50' (length=7)

$model  = Recurly_PlanModel::populateModel($record);
var_dump($model->attributes); // all strings :(

What I want is float 1402.50. What I get is a string.

I'm having the same problem with AttributeType::Bool.

What am I doing wrong?

  • 1
    Not sure if you are aware, but P&T recently added Craft::dd($variableName) as an option and has been very helpful when troubleshooting issues like this. Nov 15, 2014 at 4:51
  • Thanks @JasonMcCallister, didn't know about that. Getting the same results from Craft::dd, however. Showing strings for everything.
    – Tim Kelty
    Nov 17, 2014 at 17:17

2 Answers 2


Currently the only thing Craft does in BaseModel->setAttribute() and BaseRecord->prepAttributesForUse() is some normalization when the attribute in either case happens to be AttributeType::DateTime or AttributeType::Mixed.

All other attribute types will be returned directly as the database returned them (as a string).

However, I agree with you that we probably should be doing more to return the exact type as the attribute specifies. Since that's potentially a big breaking change, though, it'll have to wait until Craft 3.0.

The good news is, thanks to PHP's loose typing system, you can still workaround most cases.

For example a bool will come back as either the string '1' or '0'.

Using that in a PHP conditional if ($myModel->boolAttribute) will evaluate to true or false.

Using your float example: '1402.50' + 100.00, PHP will properly cast that to 1502.50.

  • Thanks for the answer Brad. The way this came up is I had a controller just dumping models to json: $this->returnJson($arrayOfModels);, but noticed everything was strings when I really wanted to retain things that were floats, bool, etc.
    – Tim Kelty
    Nov 17, 2014 at 23:53
  • Ahh... in that case, you might just need to do some casting yourself.
    – Brad Bell
    Nov 17, 2014 at 23:54
  • I'm thinking I'll override the model constructor and do my casting there, if that makes sense. But +1 for getting this on the books for Craft 3!
    – Tim Kelty
    Nov 17, 2014 at 23:56
  • I'd like to point out that this is a Yii issue. The justification by the Yii development Team was that using strings to represent integers avoids integer overflow on 32-bit machines. Personally I still think it's a bit of a silly decision.
    – Jay
    May 1, 2015 at 14:18

I ended up overriding BaseModel->setAttribute() and BaseRecord->prepAttributesForUse() in my plugin.

Works well! Right now I'm just handling Bool and Number types.

Posted this solution here: http://craftcookbook.net/recipes/324

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.