2014-10-23 7 views
2

Как получить имя первичного ключа от модели в laravel?Получить имя первичного ключа в красноречивой модели

как этот

dd(User::primaryKeyName()); // -> 'user_id' 

Я хочу, чтобы отсортировать данные по первичной, если 'порядок' пуст

$data = User::orderBy(Input::get('order', User::primaryKey()), 'ASC')->get(); 

но имеют

Non-static method Illuminate\Database\Eloquent\Model::getKeyName() should not be called statically, assuming $this from incompatible context 

ответ

5

Этот метод пытается получить значение из свойство защищенного класса return $this->primaryKey; и $this нуждается в контексте из класса instanc е. Если вам действительно нужно, чтобы получить это имя динамически, вы можете сделать это:

App::make('User')->getKeyName(); 

Так что ваш код будет выглядеть примерно так:

$data = User::orderBy(Input::get('order', App::make('User')->getKeyName()), 'ASC')->get(); 
3

Самый быстрый способ сделать это, вероятно, так:

(new User)->getKeyName(); 
(new User)->getTable(); 

Однако, я думаю, что два подхода ниже обеспечивают более чистый интерфейс к методу.

Первый подход использует статический метод на вашей базовой модели класса:

class BaseModel extends Model 
{ 
    protected static function KeyName() { 
     return (new static)->getKeyName(); 
    } 

    protected static function TableName() { 
     return (new static)->getTable(); 
    } 
} 

Тогда наследуют от этого класса в модели:

И использовать так: ModelName::KeyName();

Если у вас нет доступа к базовому классу модели, вы также можете использовать признак:

trait EloquentGetTableNameTrait 
{ 
    public static function TableName() 
    { 
     return (new static)->getTable(); 
    } 
} 

Что вы используете, как это в вашей модели:

class ModelName 
{ 
    use EloquentGetTableNameTrait; 

    ... 
} 

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

Код: https://github.com/laravel/framework/issues/1436

+1

+1 Для действующего подхода. Вы также указали на другие полезные решения, такие как объединение вызова метода при создании экземпляра '(new User) -> getTable()', который так же читаем, как 'User :: tableName()', и по существу является то же самое, поэтому вы можете включить это и в свой ответ. – Bogdan

+0

Я знаю об этом, все хорошо, но одно плохо: вы должны изменить код приложения, если хотите использовать это как модуль. В случае, если вы создаете админ-интерфейс, который может выбирать/искать/удалять/создавать строки, вы хотите просто скопировать и вставить код из одного проекта в другой, и этот код должен работать без каких-либо изменений в модели. – KoIIIeY

+0

@KoIIIeY Если вы хотите расширить основные функции моделей Eloquent, вам необходимо использовать либо наследование, как показано в этом ответе, определить черту, которая реализует эти методы, и включить ее (возможно, самый гибкий вариант здесь) или, возможно, использовать декоратор класса (что было бы излишним для этого). В любом случае вам нужен дополнительный код поверх кодовой базы Laravel.И если вы просто хотите скопировать код _copy и paste_ в другой проект, что мешает вам скопировать дополнительный код, необходимый для работы с моделями? – Bogdan

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