I am a beginning Cake user but well versed in php and frame works in general (I used to use Code Igniter). How can I call the model below and only return the Artist records and the related ArtistImage records, not the Album records.
class Artist extends AppModel {
var $name = 'Artist';
var $hasMany = array('Album', 'ArtistImage');
}
Also, can you clarify what the values for $this-Artist->recursive do?
Thanks for the help
I think the problem is your Artist Model. The correct way to add the behavior is
<?php
Class Artist extends AppModel
{
public $name = "Artist";
public $actsAs = array( 'Containable' );
}
?>
Notice the actsAs variable is plural, your model has it as $actAs = array( .. ) with the variable as a singular.
The Containable behavior (book.cakephp.org/view/474/Containable) is what you're looking for.
The recursive property (book.cakephp.org/view/439/recursive) tells how deep CakePHP should go relationship-wise when fetching records.
// Artist /app/models/artist.php
class Artist extends AppModel {
var $name = 'Artist';
var $hasMany = array('Album', 'ArtistImage');
var $actAs = array('Containable');
}
// ArtistsController /app/controllers/artists_controller.php
class ArtistsController extends AppController {
var $name = 'Artists';
public function example() {
debug( $this->Artist->find( 'all' );
debug( $this->Artist->find( 'all', array(
'recursive' => 0,
));
debug( $this->Artist->find( 'all', array(
'contain' => array(
'ArtistImage' => array(
// artist find options here i.e. fields, conditions, order etc
),
);
));
}
}
// results
// with just find( 'all' )
Array
(
[0] => Array
(
[Artist] => Array
(
[id] => 1,
[name] => Wumpscut
),
[Album] => Array
(
[0] => Array
(
[id] => 1,
[artist_id] => 1,
[name] => Bunker Gate Seven
),
[1] => Array
(
[id] => 2,
[artist_id] => 1,
[name] => Born Again
)
),
[ArtistImage] => Array
(
[0] => Array
(
[id] => 1,
[artist_id] => 1,
[file] => Bunker-Gate-Seven-Cover.jpg
),
[1] => Array
(
[id] => 2,
[artist_id] => 1,
[file] => Born-Again-Cover.jpg
)
)
),
[1] => Array
(
[Artist] => Array
(
[id] => 2,
[name] => Oneriod Psychosis
),
[Album] => Array
(
[0] => Array
(
[id] => 3,
[artist_id] => 2,
[name] => Fantasies About Illness
),
),
[ArtistImage] => Array
(
[0] => Array
(
[id] => 3,
[artist_id] => 2,
[file] => Fantasies-About-Illness-Cover.jpg
),
)
)
)
// results
// with recursive 0
Array
(
[0] => Array
(
[Artist] => Array
(
[id] => 1,
[name] => Wumpscut
),
),
[1] => Array
(
[Artist] => Array
(
[id] => 2,
[name] => Oneriod Psychosis
)
)
)
// results
// with find( 'all', array( 'contain' => array( 'ArtistImage' ))
Array
(
[0] => Array
(
[Artist] => Array
(
[id] => 1,
[name] => Wumpscut
),
[ArtistImage] => Array
(
[0] => Array
(
[id] => 1,
[artist_id] => 1,
[file] => Bunker-Gate-Seven-Cover.jpg
),
[1] => Array
(
[id] => 2,
[artist_id] => 1,
[file] => Born-Again-Cover.jpg
)
)
),
[1] => Array
(
[Artist] => Array
(
[id] => 2,
[name] => Oneriod Psychosis
),
[ArtistImage] => Array
(
[0] => Array
(
[id] => 3,
[artist_id] => 2,
[file] => Fantasies-About-Illness-Cover.jpg
),
)
)
)
Hope that helps to explain it
Can you post your controller and model into pastebin? Post those links here when you're done.
In your pastebin entry you are using...
if( $images ) {
echo( "Loading Artist Images" );
$this->Artists->recursive = 1;
$this->Artists->contains( 'ArtistImage' );
} else { ...
This wont work for a few reasons.
First - the Model names need to be Singular. I.E. Artists = Artist Second - the Containable behavior does not have a function "contains", the correct function name is also singular. I.E contains( 'ArtistImage' ) = contain( 'ArtistImage' )
So I FTFY, here ya go.
if( $images ) {
echo( "Loading Artist Images" );
$this->Artist->contain( 'ArtistImage' );
} else { ...
Hope this clarifies things for you. http://book.cakephp.org/view/474/Containable http://book.cakephp.org/view/22/CakePHP-Conventions
Also, depending on which version of Cake you are using I believe calling a model function that doesn't exist ( i.e. Model->contains( ... ) ) will try and call a stored procedure from mysql if the Model file doesn't have a function of that name.
The model is Album, so it should be $this->Album instead of $this->Albums
App::import('Model', 'Album');
$this->Album->contain('Song'); $items = $this->Album->findAllByArtistId($artist_id);