2015-06-02 10 views
1

В настоящее время мы переходим из одной базы данных в другую. Таблица в нашей базе унаследованных имеет имена столбцов, которые меньше, чем идеал, например:Eloquent Friendly Column Name

some_crazy_name__xyz

В нашей новой базе данных, мы хотели бы иметь имя столбца, как:

someCrazyName

В краткосрочной перспективе мы должны работать с данными нашей старой базы данных. В какой-то момент в ближайшем будущем мы хотели бы переключиться без необходимости реорганизации всего кода Eloquent для запроса разных имен столбцов. Например:

$model = MyModel::where('someCrazyName', '=', 1); 

В настоящее время я расширив класс модели, где все исполнители модели обеспечивают карту страшных имен дружественных имен:

class MyModel extends BaseModel { 
    $columnMap = array(
     'someCrazyName' => 'some_crazy_name__xyz' 
    ); 
} 

Это хорошо работает, где я могу использовать __get и __set в BaseModel для поиска свойства в моей карте, например:

$myModel = new MyModel; 
// ... 
echo $myModel->someCrazyName; 

Однако, это, очевидно, не очень хорошо работает с Queri без необходимости всегда использовать мою карту для поиска имен столбцов. Мне интересно, не возможно ли переопределить все методы в пределах Illuminate\Database\Eloquent\Model, Illuminate\Database\Query\Builder и Illuminate\Database\Eloquent\Builder, которые имеют дело с столбцами, в которых построенный основной запрос всегда сопоставляется с правильным столбцом? Затем, после перехода баз данных, мы можем удалить эту часть кода, а затем удалить потенциально тысячи сопоставлений имен столбцов.

ответ

1

Это то, что вам нужно: https://github.com/jarektkaczyk/eloquence/wiki/Mappable

Это не только для отображения badly_named_columns в something_useful, но также может быть использован для relational mappings:

// simple aliasing 
User::where('cool_name', 'value') // where badName = ? 

// relations, eg. User hasOne Profile 
User::where('first_name', 'Jon') // search through related profiles table 

// and obviously mutators: 
$user->first_name == $user->profile->first_name 

$user->cool_name = 'Jon' // becomes $user->badName = 'value' 
$user->cool_name; // 'Jon' 
+0

Я начал спускаться по [глобальным областям] (http://laravel.com/docs/5.0/eloquent#global-scopes), но это выглядит чище, спасибо! Возможно, запрос функции, возвращающий данные в дружественное имя, которое было запрошено, а не уродливое имя? – Jon

+0

@ Jon, пожалуйста, уточните? Полагаю, это то, о чем вы говорите в https://laracasts.com/discuss/channels/eloquent/column-alias-definitions –

+1

, что, кажется, то, что я ищу. В настоящий момент я не могу сохранить модель Eloquent, которая использует свойство Mappable. Просто добавление Mappable вызывает бесконечный цикл, в котором многократно повторяются методы Eloquent и Eloquence save(). – Jon

0

Один из способов сделать это будет с accessors.

Например, в MyModel можно определить аксессор для some_crazy_name__xyz колонны, как это:

public function getSomeCrazyNameAttribute() 
{ 
    return $this->attributes['some_crazy_name__xyz']; 
} 

Вы можете прозрачно относиться к этому колонку с $mymodel->someCrazyName. Вы также можете определить мутатор, чтобы установить значение.

По общему признанию, это может быть не лучшее решение, если у вас есть МНОГИЕ значения, подобные этому. Но у него есть одно важное преимущество: позже, если вы реорганизуете свою базу данных так, чтобы столбец some_crazy_name__xyz был фактически вызван someCrazyName, все, что вам нужно сделать, это удалить эту функцию из вашей модели. И, по крайней мере, на мой взгляд, это проще, чем пытаться переопределить множество методов для различных классов.

И, к сожалению, он не подходит для использования имен столбцов в запросах. Для этого вы можете посмотреть на repository pattern. Но в любом случае, похоже, что будет много кодирования.

Наконец, вы не указали, какую базу данных вы используете. Если это MySQL, можно создать updatable and insertable views. Используя представление, вы можете просто сопоставить старые имена столбцов с новыми и указать свою модель Eloquent на представление вместо таблицы. Другие серверы баз данных могут обеспечивать аналогичную функциональность.

+0

К сожалению, у нас есть тонны этих столбцов, поэтому использование __get и __set немного легче, чем аксессоры. Образец репозитория - хорошая идея; но вы правы, я, вероятно, буду писать много кода. – Jon

Смежные вопросы