yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.91k forks source link

Model::i access ? #10938

Closed mmuruev closed 8 years ago

mmuruev commented 8 years ago

I faced weird thing with ActiveRecord class and REST controller(ActiveController).

{
  "name": "Database Exception",
  "message": "SQLSTATE[42703]: Undefined column: 7 ERROR:  column \"i\" does not exist\nLINE 1: SELECT * FROM \"currency\" WHERE \"i\"=$1\n                                       ^\nThe SQL being executed was: SELECT * FROM \"currency\" WHERE \"i\"='EUR'",
  "code": 42703,
  "type": "yii\db\Exception",
  "file": "/home/vagrant/Code/spring/vendor/yiisoft/yii2/db/Schema.php",
  "line": 628
}

Seems like this 'i' popup from nothere. Nothing like this is mentioned in my models. Seems like a bug? I'm running php 7.0

samdark commented 8 years ago

Nothing could popup from nowhere. Please show stacktrace.

mmuruev commented 8 years ago
{
  "name": "Database Exception",
  "message": "SQLSTATE[42703]: Undefined column: 7 ERROR:  column \"i\" does not exist\nLINE 1: SELECT * FROM \"currency\" WHERE \"i\"=$1\n                                       ^\nThe SQL being executed was: SELECT * FROM \"currency\" WHERE \"i\"='EUR'",
  "code": 42703,
  "type": "yii\db\Exception",
  "file": "/home/vagrant/Code/spring/vendor/yiisoft/yii2/db/Schema.php",
  "line": 628,
  "stack-trace": [
    "#0 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/Command.php(855): yii\db\Schema->convertException(Object(PDOException), 'SELECT * FROM \"...')",
    "#1 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/Command.php(376): yii\db\Command->queryInternal('fetch', NULL)",
    "#2 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/Query.php(247): yii\db\Command->queryOne()",
    "#3 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/ActiveQuery.php(290): yii\db\Query->one(NULL)",
    "#4 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/BaseActiveRecord.php(102): yii\db\ActiveQuery->one()",
    "#5 /home/vagrant/Code/spring/vendor/yiisoft/yii2/rest/Action.php(95): yii\db\BaseActiveRecord::findOne('EUR')",
    "#6 /home/vagrant/Code/spring/vendor/yiisoft/yii2/rest/ViewAction.php(27): yii\rest\Action->findModel('EUR')",
    "#7 [internal function]: yii\rest\ViewAction->run('EUR')",
    "#8 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Action.php(92): call_user_func_array(Array, Array)",
    "#9 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Controller.php(154): yii\base\Action->runWithParams(Array)",
    "#10 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Module.php(454): yii\base\Controller->runAction('view', Array)",
    "#11 /home/vagrant/Code/spring/vendor/yiisoft/yii2/web/Application.php(84): yii\base\Module->runAction('v1/currency/vie...', Array)",
    "#12 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))",
    "#13 /home/vagrant/Code/spring/api/web/index.php(25): yii\base\Application->run()",
    "#14 {main}"
  ],
  "error-info": [
    "42703",
    7,
    "ERROR:  column \"i\" does not exist\nLINE 1: SELECT * FROM \"currency\" WHERE \"i\"=$1\n                                       ^"
  ],
  "previous": {
    "name": "Exception",
    "message": "SQLSTATE[42703]: Undefined column: 7 ERROR:  column \"i\" does not exist\nLINE 1: SELECT * FROM \"currency\" WHERE \"i\"=$1\n                                       ^",
    "code": "42703",
    "type": "PDOException",
    "file": "/home/vagrant/Code/spring/vendor/yiisoft/yii2/db/Command.php",
    "line": 840,
    "stack-trace": [
      "#0 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/Command.php(840): PDOStatement->execute()",
      "#1 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/Command.php(376): yii\db\Command->queryInternal('fetch', NULL)",
      "#2 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/Query.php(247): yii\db\Command->queryOne()",
      "#3 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/ActiveQuery.php(290): yii\db\Query->one(NULL)",
      "#4 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/BaseActiveRecord.php(102): yii\db\ActiveQuery->one()",
      "#5 /home/vagrant/Code/spring/vendor/yiisoft/yii2/rest/Action.php(95): yii\db\BaseActiveRecord::findOne('EUR')",
      "#6 /home/vagrant/Code/spring/vendor/yiisoft/yii2/rest/ViewAction.php(27): yii\rest\Action->findModel('EUR')",
      "#7 [internal function]: yii\rest\ViewAction->run('EUR')",
      "#8 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Action.php(92): call_user_func_array(Array, Array)",
      "#9 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Controller.php(154): yii\base\Action->runWithParams(Array)",
      "#10 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Module.php(454): yii\base\Controller->runAction('view', Array)",
      "#11 /home/vagrant/Code/spring/vendor/yiisoft/yii2/web/Application.php(84): yii\base\Module->runAction('v1/currency/vie...', Array)",
      "#12 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))",
mmuruev commented 8 years ago

Almost the same issue happens then just trying get all fields

{
  "name": "Unknown Property",
  "message": "Getting unknown property: api\modules\v1\models\Currency::i",
  "code": 0,
  "type": "yii\base\UnknownPropertyException",
  "file": "/home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Component.php",
  "line": 143,
  "stack-trace": [
    "#0 /home/vagrant/Code/spring/vendor/yiisoft/yii2/db/BaseActiveRecord.php(247): yii\base\Component->__get('i')",
    "#1 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Model.php(984): yii\db\BaseActiveRecord->__get('i')",
    "#2 /home/vagrant/Code/spring/vendor/yiisoft/yii2/data/ActiveDataProvider.php(138): yii\base\Model->offsetGet('i')",
    "#3 /home/vagrant/Code/spring/vendor/yiisoft/yii2/data/BaseDataProvider.php(82): yii\data\ActiveDataProvider->prepareKeys(Array)",
    "#4 /home/vagrant/Code/spring/vendor/yiisoft/yii2/data/BaseDataProvider.php(92): yii\data\BaseDataProvider->prepare()",
    "#5 /home/vagrant/Code/spring/vendor/yiisoft/yii2/rest/Serializer.php(174): yii\data\BaseDataProvider->getModels()",
    "#6 /home/vagrant/Code/spring/vendor/yiisoft/yii2/rest/Serializer.php(143): yii\rest\Serializer->serializeDataProvider(Object(yii\data\ActiveDataProvider))",
    "#7 /home/vagrant/Code/spring/vendor/yiisoft/yii2/rest/Controller.php(97): yii\rest\Serializer->serialize(Object(yii\data\ActiveDataProvider))",
    "#8 /home/vagrant/Code/spring/vendor/yiisoft/yii2/rest/Controller.php(75): yii\rest\Controller->serializeData(Object(yii\data\ActiveDataProvider))",
    "#9 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Controller.php(156): yii\rest\Controller->afterAction(Object(yii\rest\IndexAction), Object(yii\data\ActiveDataProvider))",
    "#10 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Module.php(454): yii\base\Controller->runAction('index', Array)",
    "#11 /home/vagrant/Code/spring/vendor/yiisoft/yii2/web/Application.php(84): yii\base\Module->runAction('v1/currency/ind...', Array)",
    "#12 /home/vagrant/Code/spring/vendor/yiisoft/yii2/base/Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))",
    "#13 /home/vagrant/Code/spring/api/web/index.php(25): yii\base\Application->run()",
    "#14 {main}"
  ]
}

so url just /currencies ..no mention any field at all.

klimov-paul commented 8 years ago

Please, provide your controller and model code and data provider configuration.

samdark commented 8 years ago

Looks like i is a primary key of your model. Additionally to what @klimov-paul asked I'd like to get SQL to create a table for that model.

samdark commented 8 years ago

Oh, and another question. Is that MySQL?

mmuruev commented 8 years ago

Not realy. Model has enum key as "iso" so i never mentioned

samdark commented 8 years ago

@mmuruev OK. Please provide info we've asked for so we can reproduce the issue.

mmuruev commented 8 years ago
class CountryController extends ActiveController
{
    public $modelClass = 'api\modules\v1\models\Country';
}
class Country extends ActiveRecord
{
    /**
     *  Table name in DB
     */
    const TABLE_NAME = 'country';

    /**
     *  Primary key
     */
    const FIELD_ID = 'iso';

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return static::TABLE_NAME;
    }

   public static function primaryKey()
    {
        return static::FIELD_ID;
    }
}

I've removed rules() and so on nothing interesting in it. also primaryKey() actually in parent model class.

Schema CREATE TABLE country

(
    iso COUNTRY_TYPE PRIMARY KEY NOT NULL,
    name VARCHAR(80) NOT NULL,
    nicename VARCHAR(80) NOT NULL,
    iso3 CHAR(3) DEFAULT NULL::bpchar,
    numcode INTEGER,
    phonecode INTEGER NOT NULL,
    currency CURRENCY_TYPE
);
cebe commented 8 years ago

primary key method must return an array, not a string.