2013-05-30 55 views
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')); 

这里来了棘手的部分。如何在翻译中插入翻译过的食谱?我已经走到这一步:

$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 
    ) 
); 

它不设置时间戳,但因为我猜,雄辩的特点。有没有办法让它保持100%的口才?我不能这样做:

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

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

回答

0

好吧,我没有测试过这一点,但也有几件事情我会改变:

  • 我会改变“语言”表有以下字段:“ID”, '首字母缩写'和'displayname'。
  • 然后,我会将'translated_recipe'表中的'language_id'字段更改为无符号整数。

(在'语言'表中将主键设置为'id'真的很勇敢 - 它甚至不是一个单词的松散含义!这可能是问题的原因。雄辩可能会期待你的主键是你没有的自动递增的字段。)

此外,充分利用框架中提供的“免费”功能,收取相对较小的费用'如下:

  1. 以复数形式命名你的表格(语言,食谱,翻译)
  2. 设置主键是自动递增场(显然是一个整数)

您可以滚动到一到Dayle Rees Codehappy tutorial许多部分,其是为那些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'); 
    } 
} 
+0

感谢您的列命名和IDS的建议!有一件事我不明白。我对数据库建模相当陌生,所以请耐心等待。为什么我需要额外的桌子和多对多的关系?一个食谱可以有许多个翻译食谱,一个翻译食谱属于一个食谱。一个translated_recipe只能属于一种语言,一种语言可以有很多translation_recipes。还是我错过了一些基本的东西? – bjoupp

+0

你是完全正确的! (我会编辑我的答案)。你其实不需要第四张桌子。 – kJamesy