在 Laravel 查詢中 setTablePrefix


目前遇到的情況是.有一個表.但需要在裡面存不同語系的資料.
如 en_us_message, zh_tw_message, zh_cn_message.
除了建立新的 ORM Model 外.好像就沒方法在 ORM 查詢時更改表名.
當然可以用 DB::table Query 來查詢.但寫法比較長.
最後只好找了一下和改了一下找回來的方法

  1. 建立一個 Factory 來生成 Model 並在生成時設置他的對應表名
  2. 在查詢時使用 ModelFactory::fromTable(ModelName, TableName) 解決

但問題是.這種生成會導致 create 和 all 這類方法失效.
失效指的是他不能夠使用指的 TableName.
原因是這些方法會自已生成 Model (new static) 而不用現有的 instance.

當然.除了這種方法還可以考慮用 laravel-translatable 這玩意

筆記一下

工廠類

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
class ModelFactory extends Eloquent {

protected static $_table;

public static function fromTable($model, $table, $attributes = Array()) {
$instance = null;

if (class_exists($model) === true) {
$instance = new $model($attributes);
$instance->setTable($table);
} else {
$instance = new static($attributes);
$instance->setTable($table);
}

return $instance;
}

public function setTable($table) {
static::$_table = $table;
}

public function getTable() {
return static::$_table;
}

}

使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
Route::get('/', function() {
// Do not use create, all method (it will new object can not overwrite prefix)

$langs = ['en_us', 'zh_tw', 'zh_cn'];

foreach($langs as $lang) {
$table = $lang.'_message';

ModelFactory::fromTable('message', $table)->fill([
'content' => 'content_'.$lang
])->save();
}

foreach($langs as $lang) {
$table = $lang.'_message';

$messages = ModelFactory::fromTable('message', $table)->get();

echo "<h3>".$lang."</h3>";
foreach($messages as $message) {
echo "<p>".$message->content."</p>";
}
}

});

資料庫結構

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateMessageTable extends Migration {

/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('en_us_message', function($table) {
$table->increments('id');
$table->string('content', 100);
$table->timestamps();
});

Schema::create('zh_tw_message', function($table) {
$table->increments('id');
$table->string('content', 100);
$table->timestamps();
});

Schema::create('zh_cn_message', function($table) {
$table->increments('id');
$table->string('content', 100);
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('en_us_message');
Schema::dropIfExists('zh_tw_message');
Schema::dropIfExists('zh_cn_message');
}

}