CakePHP actsAs Translate和$Model::find()

CakePHP actsAs Translate和$Model::find(),cakephp,translate,Cakephp,Translate,我已将翻译行为附加到我的一个模型上,在这方面我有一些缺点: 1) 如果在将行为附加到模型时未将所有字段中的数据保存为参数,$model::find()方法不会获取插入的行 public $actsAs = array( 'Translate' => array( 'title' => 'title_Translation', 'description' => 'description_Translation', 'desc

我已将翻译行为附加到我的一个模型上,在这方面我有一些缺点:

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) 我如何在应用程序的管理端获取所有记录(无论记录以何种语言保存),以便列出这些记录,以便用户可以对其进行更改(编辑数据、以多种语言保存数据)?现在,我只能获取与当前语言对应的记录(从Configure或set显式读取)


谢谢大家!

好吧,我可能会晚一点,但无论如何

1) Cake在获取行及其关联的翻译时使用内部联接,所以基本上没有简单的方法。您必须确保每次都保存每个可翻译字段,即使您只是将其保存为空白。唯一的替代方法是对核心进行黑客攻击,使其使用左连接而不是内部连接,但不要这样做

2) 食谱介绍了如何在此处获取所有记录:

现在,大多数情况下,您可能只希望获得一个转换,因此不希望修改模型中$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');

希望有帮助

好吧,我可能会晚一点,但无论如何

1) Cake在获取行及其关联的翻译时使用内部联接,所以基本上没有简单的方法。您必须确保每次都保存每个可翻译字段,即使您只是将其保存为空白。唯一的替代方法是对核心进行黑客攻击,使其使用左连接而不是内部连接,但不要这样做

2) 食谱介绍了如何在此处获取所有记录:

现在,大多数情况下,您可能只希望获得一个转换,因此不希望修改模型中$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');

希望有帮助

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

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


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

我解决了这个问题,我将翻译行为复制到app/Model/Behavior(只是为了避免将来升级时出现问题,并保留原始行为以防万一),然后我更改了行为的_addJoin(…)方法,刚刚在第255行将连接类型从内部更改为左侧(我使用cake 2.2.3)

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


除了检查翻译字段是否为空之外,没有发现任何缺点。

不确定它是否对您的情况有帮助,但您也可以使用 在调用find()之前设置区域设置的数组


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

不确定这对您的情况是否有帮助,但您也可以使用 在调用find()之前设置区域设置的数组


这样,即使没有所有可能的翻译,你也可以得到所有的记录。

非常感谢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条件下,如果会话中没有设置语言环境,我会动态禁用Translate行为以获取原始内容(我使用基本链接在语言之间切换)

非常感谢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条件下,如果会话中没有设置语言环境,我会动态禁用Translate行为以获取原始内容(我使用基本链接在语言之间切换)

这里也有同样的问题。生成的查询对翻译的每个字段都与翻译表进行内部联接,因此,如果翻译表中至少有一个字段不存在,则甚至不会检索原始记录。如果您需要在现有模型中添加新的已翻译字段,那么您就完成了。我也遇到了同样的问题,并编写了一些代码来修复它。。。基本上,在添加一个新的可翻译字段之后,您可以执行以下代码来检查并在数据库中为所有现有行添加新的翻译记录。看这里:这里有同样的问题。生成的查询对翻译的每个字段都与翻译表进行内部联接,因此,如果翻译表中至少有一个字段不存在,则甚至不会检索原始记录。如果您需要在现有模型中添加新的已翻译字段,那么您就完成了。我也遇到了同样的问题,并编写了一些代码来修复它。。。基本上,在你之后