Not Able To Correctly Apply Scopes To A Model

So I have a model ‘Plants’ and one of the columns in the underlying table is

"grp VARCHAR(128) NOT NULL"

per the sql that created the table.

I am attempting to use a parameterized scope method to only return plants that belong to a specific group.

When following the stack trace error I noted the following. In my Plants model I have the following scope set up




public function bygrpid($grpid)

{

	$this->getDbCriteria()->mergeWith(array(

		'grp'=>$grpid,

		));

	return $this;

}



Per the stack trace the group is is being picked up properly and being incorporated into an array. So far so good.

From there it fires off the CDbCriteria->mergeWith() method with the array in tow, still so far so good.

In the mergeWith() method it sees that it has been handed an array("grp" => "916bca531500b542f90ae4be3b279aba") and runs this snippet of code




$criteria=new self($criteria);



which takes my array and tries to construct a new cDbCriteria in the __construct() method and this is where I run into troubles.




foreach($data as $name=>$value)

	$this->$name=$value;



The error occurs at the


$this->$name=$value

Here the error is:

Property "CDbCriteria.grp" is not defined.

Now ‘grp’ is a column in the underlying table and in


class Plants extends CActiveRecord{}   -- No I did not close the brackets so quickly in my code, just my way of showing a class name.

I have:


public function search()

{

	$criteria=new CDbCriteria;


	....

	$criteria->compare('grp',$this->grp);

	....


	return new CActiveDataProvider($this, array(

		'criteria'=>$criteria,

	));

}

grp also shows up in my atributesLabel()


public function rules()

{

	return array(

		array('grp', 'length', 'max'=>128),

		// The following rule is used by search().

		// Please remove those attributes that should not be searched.

		array('birthday', 'safe', 'on'=>'insert'),

		array('pltindex, id, strain, location, currstg, grp, birthday', 'safe', 'on'=>'search'),

	);

}

The value in grp is an MD5 hash of the group name and each plant in the plants table has a grp associated with it and numerous plants can have the same grp id. Additionally grp is used as a foreign key to the Groups model to get additional info about the group if needed.

What am I missing here so that this scope works properly.

Merge with adds the array keys as CDbCriteria properties, in effect you are doing this:




$criteria = new CDbCriteria;

$criteria->grp = $grpid;



As you can see this will fail because CDbCriteria has no such member.




public function bygrpid($grpid)

{

        $this->getDbCriteria()->mergeWith(array(

                'condition' => 'grp = :grpid',

                'params' => array(':grpid' => $grpid),

                ));

        return $this;

}

is more like what you want. Or




public function bygrpid($grpid)

{

        $criteria = new CDbCriteria;

        $criteria->compare('grp', $grpid);

        $this->getDbCriteria()->mergeWith($criteria);

        return $this;

}



Ah, yes I see. Thank you.

The cDbCriteria is wanting to build a sql query for the model or something along those lines. In my criteria I wanted to add to this query with an additional restriction of gpr=916… so as to only return records meeting this restriction. My line of


array('grp'=>$grpid,)

would need to have been used in the context of adding a condition to the sql query. And what do you know, there is this that I could have used


$this->getDbCriteria()->addColumnCondition(array('grp'=>$grpid,));

but here I will keep with your suggestion since the mergeWith() seems to imply better what I am wanting to do and that method may have thought about other things that I am as yet unaware of.