1

我刚刚开始学习 Laravel 4,遇到了一个小问题,我很好奇是否有解决方案。我有一个多语言食谱数据库,简而言之,我的数据库建模如下:

Schema::create('language', function(Blueprint $table) {
    $table->string('id', 2)->primary();
    $table->string('display_name');
    $table->timestamps();
});

Schema::create('recipe', function(Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('slug')->unique();
    $table->timestamps();
});

Schema::create('translated_recipe', function(Blueprint $table) {
    $table->increments('id');
    $table->integer('recipe_id')->unsigned();
    $table->foreign('recipe_id')->references('id')->on('recipe')->onDelete('cascade');
    $table->string('language_id', 2);
    $table->foreign('language_id')->references('id')->on('language');
    $table->string('translated_name')
    $table->timestamps();
});

我的模型如下所示:

class Language extends Eloquent {
    protected $table = 'language';
    public function translatedRecipes() {
        return $this->hasMany('TranslatedRecipe');
    }
}

class Recipe extends Eloquent { 
    protected $table = 'recipe';
    public function translations() {
        return $this->hasMany('TranslatedRecipe');
    }
}

class TranslatedRecipe extends Eloquent {
    protected $table = 'translated_recipe';
    public function recipe() {
        return $this->belongsTo('Recipe');
    }
}

然后我有一些基本的播种:

Language::create(array('id' => 'en', 'display_name' => 'English'));
Recipe::create(array('name' => 'First Recipe', 'slug' => 'first_recipe'));

棘手的部分来了。如何使用 Eloquent 插入翻译后的食谱?我已经走到了这一步:

$recipe = Recipe::all()->first();
$lang = Language::all()->first();
$translatedRecipe = new TranslatedRecipe;
$translatedRecipe->translated_name = $lang->display_name.' '.$recipe->name;

我可以使用查询生成器轻松地进行 INSERT:

DB::table('translated_recipe')->insert(
    array(
        'recipe_id' => $recipe->id, 
        'language_id' => $lang->id,
        'translated_name' => $translatedRecipe->translated_name
    )
);

它没有设置时间戳,因为我猜这是 Eloquent 的一个特性。有没有办法让它 100% 雄辩?我不能这样做:

$translatedRecipe = $recipe->translations()->save($translatedRecipe);

...因为 SQL 由于缺少第二个外键而引发“完整性约束违规:1452 ...”错误。

4

1 回答 1

0

好的,我还没有对此进行测试,但有几件事我会改变:

  • 我会将“语言”表更改为具有以下字段:“ id ”、“ initials ”和“ displayname ”。
  • 然后,我会将“ translated_recipe ”表中的“ language_id ”字段更改为无符号整数。

(在 'language' 表中将主键设置为 'id' 真的很勇敢 - 从这个词的松散含义来看,它甚至不是一个 id!这可能是问题的原因。Eloquent 可能期待你的主键键是您没有的自动递增字段。)

此外,最好以相对较小的“费用”来充分利用框架中提供的“免费”功能,例如:

  1. 以复数形式命名您的表格(语言、食谱、翻译)
  2. 将主键设置为自动递增字段(显然是整数)

你可以滚动到Dayle Rees Codehappy 教程的一对多部分,该教程适用于 Laravel 3,但适合我们的目的。如果你想学习框架的其他特性,或者花一两块钱买他的 Laravel 4 的CodeBright书。(我还没有)

最后,您的“translated_recipe”表中没有“short_description”和“description”字段!它的工作是一个奇迹!

        Schema::create('languages', function($table) 
    {
        $table->engine = 'InnoDB';

        $table->increments('id');
        $table->string('initials', 2)->unique();
        $table->string('display_name');
        $table->timestamps();
    });

    Schema::create('recipes', function($table) 
    {
        $table->engine = 'InnoDB';

        $table->increments('id');
        $table->string('name');
        $table->string('slug')->unique();
        $table->timestamps();
    });

    Schema::create('translations', function($table) 
    {
        $table->engine = 'InnoDB';

        $table->increments('id');
        $table->integer('recipe_id')->unsigned();
        $table->integer('language_id')->unsigned();
        $table->string('translated_name');
        $table->timestamps();

        $table->foreign('recipe_id')->references('id')->on('recipe')->onDelete('cascade');
        $table->foreign('language_id')->references('id')->on('language')->onDelete('cascade');          
    });

楷模

class Language extends Eloquent {
  public function translations() 
  {
    return $this->hasMany('Translation');
  }
}

class Recipe extends Eloquent { 
  public function translations() 
  {
    return $this->hasMany('Translation');
  }
}

class Translation extends Eloquent {
  public function recipe() 
  {
     return $this->belongsTo('Recipe');
  }

  public function language() 
  {
     return $this->belongsTo('Language');
  }
}
于 2013-06-03T16:32:14.663 回答