1

我已将翻译行为附加到我的一个模型中,对此我有一些缺点:

1) 如果在将行为附加到模型时,我没有在作为参数传递的所有字段中保存数据,则 $Model::find() 方法不会获取插入的行。

public $actsAs = array(
    'Translate' => array(
        'title' => 'title_Translation',
        'description' => 'description_Translation',
        'description_long' => 'description_long_Translation'
    )
);

例如:如果我$Model::save()只将值传递给方法'title',则数据将被保存,即使在 i18n 表中,但$Model::find()什么也得不到。我必须传递所有字段的数据。

我可以强制它检索那些记录吗?

2) 我怎样才能在应用程序的管理端获取所有记录(无论保存记录的语言如何)以便列出它们以便用户可以更改它(编辑数据,以多种语言保存数据)?现在,我只能获取与当前语言对应的记录(从配置中读取或显式设置)..

谢谢!

4

4 回答 4

4

我解决了它,我将 TranslateBehavior 复制到 app/Model/Behavior (只是为了避免将来升级时出现问题并保留原来的以防万一)然后我更改了行为的 _addJoin(...) 方法,只是更改了第 255 行从 INNER 到 LEFT 的连接类型(我使用 cake 2.2.3)。

现在,如果一条记录存在,它总是会被检索到,即使翻译的字段丢失。

除了需要检查翻译字段是否为空之外,没有看到任何缺点。

于 2012-11-16T13:02:52.243 回答
2

好吧,我可能有点晚了,但无论如何......

1)Cake 在获取一行时使用 INNER JOIN 并且它是相关的翻译,所以基本上没有简单的方法解决这个问题。您必须确保每次都保存每个可翻译字段 - 即使您只是将其保存为空白。唯一的选择是绕过核心使其使用左连接而不是内连接 - 但不要这样做。

2)食谱解释了如何在这里获取所有记录:http: //book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html#retrieve-all-translation-records-for-a-field

现在,可能大多数时候您只想获得一个翻译,因此您不想修改模型中 $actsAs['Translate'] 数组的定义。所以我所做的是在 AppModel.php 中设置了一个方法,它可以即时修改 $actsAs['Translate'] 数组:

/*  
 * 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.
}

因此,如果它是一个管理方法(或任何其他您想要所有翻译的情况),您在查找之前调用该代码:

$this->MyModel->bindAllTranslations();
$this->MyModel->find('all');

希望有帮助!

于 2012-11-16T05:16:04.973 回答
0

不确定它是否对您有帮助,但您也可以在调用find()之前使用数组来设置语言环境

$this->YourModel->locale = array("ENG", "GER", "JAP");

这样,您将始终获得所有记录,即使它们没有所有可能的翻译。

于 2015-05-04T22:35:31.000 回答
0

非常感谢eleonzx,十年来我一直有这个问题,有了你的简单回答,我现在可以继续前进了!所以再次感谢。

也许这段代码可以帮助很多人:

在我的 AppController beforeFilter 方法中,我调用 _setLanguage

private function _setLanguage() {
    if($this->Session->read('Config.language')){
        $locale = $this->Session->read('Config.language');
        $this->{$this->modelClass}->setLocale($locale);
    }else{
        $this->{$this->modelClass}->Behaviors->disable('Translate');
    }
}

在 else 条件下,如果会话中没有设置语言环境,我会即时禁用翻译行为以获取原始内容(我使用基本链接在语言之间切换)。

于 2017-01-11T21:44:35.200 回答