Issue
I have attached the Translate behavior to one of my models and I have some shortcomings regarding this:
1) If I don't save data in all fields passed as params when attaching the behavior to the model, $Model::find() method doesn't get the inserted rows.
public $actsAs = array(
'Translate' => array(
'title' => 'title_Translation',
'description' => 'description_Translation',
'description_long' => 'description_long_Translation'
)
);
Ex: if i pass to $Model::save()
method only a value for 'title'
, the data is saved, even in the i18n table, but the $Model::find()
doesn't get anything. I must pass data for all the fields.
Can I force it to retrieve those records ?
2) How can I get all the records in the admin side of the application (regardless of the language in which a record is saved) in order to list them so the user can alter it (edit data, save data in multiple languages)? Right now, I can only get the records that correspond to the current language (read from Configure or set explicitly)..
Thank you!
Solution
OK, I might be a bit late, but anyway...
1) Cake uses an INNER JOIN when fetching a row and it's associated translations, so basically there's no easy way around this. You have to make sure you save every translatable field, every time - even if you just save it as blank. The only alternative would be to go hacking round the core to make it use a left join rather than an inner join - but don't do that.
2) The cookbook explains how to fetch all records here: http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html#retrieve-all-translation-records-for-a-field
Now, probably most of the time you want to get just one translation, so you don't want to modify the definition of your $actsAs['Translate'] array in your model. So what I did, was set up a method in AppModel.php which modifies the $actsAs['Translate'] array on the fly:
/*
* See http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html#using-the-bindtranslation-method
* This is for making it so we fetch all translations, as opposed to just that of the current locale.
* Used for eg. editing (multiple translations) via the admin interface.
*/
public function bindAllTranslations(){
$translatableFields = $this->actsAs['Translate'];
$keyValueFields = array();
foreach($translatableFields as $field){
$keyValueFields[$field] = $field.'Translation';
}
$this->bindTranslation($keyValueFields,false); // false means it will be changed for all future DB transactions in this page request - and won't be reset after the next transaction.
}
So, if it's an admin method (or any other situation you want all translations) you call that code before doing a find:
$this->MyModel->bindAllTranslations();
$this->MyModel->find('all');
Hope that helps!
Answered By - joshua.paling
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.