matowc1991
(Mat Owczarek)
February 13, 2011, 5:19pm
1
[font="Arial"]
Hello
I’ve got a problem with implementing my idea into Yii application.
The idea is:
When I do a find
$shelf = Shelf::model()->with(array('books' => array('condition' => 'price=1')))->findByAttributes(array(
'active' => '3',
'room' => $room
));
and there is an item which matches given parameters => it returns (of course) that item (model),
BUT when there isn’t such one => it should creates a new instance of model Shelf, fills it with some data (i.e. ‘active’ = 0 and so on…) and returns it!
I was planning to do it by afterFind method, but it seems that this method isn’t being called when a find ends with fail (null)
Of course I can do it roughly by:
if(!$shelf)
{
$shelf=new Shelf();
$shelf->active = 0;
$shelf->books = Book:model()->findAllByAttributes(...);
if(!count($shelf->books))
{
$shelf->books = array();
$shelf->books[0] = Book();
$shelf->books[0]->name = 'Example';
}
}
but it isn’t a nice solution…[/font]
Thanks so much for your help!
andy_s
(Arekandrei)
February 13, 2011, 5:51pm
2
Why not just create a static method returning a new model with all filled data you need?
class Shelf extends CActiveRecord
{
// ...
public static function createNewShelf()
{
$shelf = new Shelf;
// your code there...
return $shelf;
}
$shelf = Shelf::model()->with(array('books' => array('condition' => 'price=1')))->findByAttributes(array(
'active' => '3',
'room' => $room
));
if ($shelf === null)
$shelf = Shelf::createNewShelf();
But if you want all find methods to return you a new model, then take a look at the populateRecord() method. You can override it as follows:
public function populateRecord($attributes,$callAfterFind=true)
{
$model = parent::populateRecord($attributes,$callAfterFind);
if ($model === null)
{
$model = new Shelf;
// your code there...
}
return $model
}
matowc1991
(Mat Owczarek)
February 13, 2011, 6:12pm
3
Thanks for your help, but it seems that populateRecord method is being called also only when findBy method returns with success.
I’ve added
public function populateRecord($attributes,$callAfterFind=true)
{
$model = parent::populateRecord($attributes,$callAfterFind);
if ($model === null)
{
die();
}
return $model;
}
and it doesn’t die and findBy method returns no results (null).
matowc1991
(Mat Owczarek)
February 13, 2011, 6:19pm
4
And yes - I need it to be done with all calls of findBy method. And it’s a bit more complex, so I don’t want to use your first solution
I need to implement this functionality to at least two models, so for example:
when Shelf::findBy method returns null the script should do:
$shelf = new Shelf();
$shelf->books = Book::model()->findBy(...);
and Book:findBy may return null as well, so then it should do:
$book = new Book();
return $book
and this returned $book should be a value of $shelf->books
The idea of use populateRecord will be brilliant, if it is being called even when findBy returns fail, but it isn’t
However, thanks for your ideas.
andy_s
(Arekandrei)
February 13, 2011, 7:46pm
5
Looks like populateRecord() isn’t called if with() is used, what’s a surprise for me
But you can still override 2 or 3 find methods you need.