2015-05-05 3 views
2

В настоящее время я борюсь со сложной проблемой отношений SQL/Laravel.Настройки пользователя, разбитые по типам

Для каждого пользователя мне нужно установить настройки. Эти предпочтения включают в себя четыре различных типа:

  1. Locations
  2. Конкуренты
  3. платформы
  4. Графики

Желаемые отношения будут что-то вроде:

$user = User::find(1) 
//Retrieves all user locations 
$user->preferences->locations 
//Retrieves all user competitors 
$user->preferences->competitors 
//Retrieves all user platforms 
$user->preferences->platforms 
//Retrieves all graphs 
$user->preferences->graphs 

Я изменил текущая структура данных е раз, потому что я был не в состоянии понять это, но это выглядит как-то эту таблицу:

  • user_preferences
    • ID
    • user_id

А затем для каждого тип предпочтений (места, конкуренты и т. д.), другая таблица:

  • user_preferences_locations
    • user_preferences_id
    • LOCATION_ID ИЛИ competitor_id и т.д.

Далее усложняя этот беспорядок является то, что четыре типа предпочтения не совпадают с таблицами, на которых они предназначены, чтобы присоединиться к. Например, как места, так и конкуренты должны присоединиться к таблице Business, которую я имею (их идентификаторы в этой сводной таблице являются идентификатором бизнеса), а платформам необходимо присоединиться к таблице сервисов.

Вопрос в том, как я собираюсь определить эти сложные отношения? Будет ли это случай, когда я использую полиморфные отношения? Мне нужна модель для каждой сводной таблицы (user_preferences_location и т. Д.)? Сейчас я полностью перегружен, и я изо всех сил пытаюсь это сделать в течение нескольких часов. Любая помощь будет чрезвычайно полезна.

Спасибо.

ответ

0

Я немного изменил структуру данных. Я добавил таблицу user_preferences, которая действительно является только первичным ключом и user_id. Затем я сделал три мои сводные таблицы имеют user_preferences_id, а затем я создал модель в красноречив таким образом:

class UserPreferences extends Model 
{ 
    public function user() 
    { 
     return $this->belongsTo(User::class); 
    } 

    public function locations() 
    { 
     return $this->belongsToMany(Business::class, "user_preference_location"); 
    } 

    public function competitors() 
    { 
     return $this->belongsToMany(Business::class, "user_preference_competitor"); 
    } 

    public function platforms() 
    { 
     return $this->belongsToMany(Service::class, "user_preference_platform"); 
    } 
} 

Теперь я могу получить доступ к моим свойства с помощью простого $user->preferences->locations. Это не так чисто, как мне бы хотелось: например, я предпочел бы иметь одну таблицу предпочтений, а не три ее оси, или даже иметь один стержень между user_preferences и его типами. Но это что-то еще на другой день.

0

Если таблицы предпочтений содержат только идентификаторы, то кажется, что вам нужны только 4 сводные таблицы между пользователями и местоположениями, графиками и т. Д. Затем вы можете получить доступ к ним через пользовательские> местоположения или настроить метод доступа, который вернет их в необходимом формате

public function getPreferencesAttribute($value) 
{ 
    $preferences = new stdClass(); 
    $preferences->locations => $this->locations; 
    $preferences->graphs => $this->graphs; 
    return $preferences; 
} 
2

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

$user = User::find(1) 
//Retrieves all user locations 
$user->locationPreferences 
//Retrieves all user competitors 
$user->competitorPreferences 
//Retrieves all user platforms 
$user->platformPreferences 
//Retrieves all graphs 
$user->graphPreferences 

В чем разница? Это всего лишь четыре простых «hasMany» отношения между моделью пользователя и моделями для каждого из четырех различных типов предпочтений.Тогда ваши модели выглядеть следующим образом:

class LocationPreference extends Model { 
} 

// plus classes for the other types of preferences... 

class User extends Model { 

    public function locationPreferences() { 
     return $this->hasMany("LocationPreference"); 
    } 

    // plus methods for the other types of preferences... 
} 

И таблицы просты:

CREATE TABLE location_preferences (
    id INT AUTOINCREMENT, 
    user_id INT, 
    -- plus whatever other fields you need 
); 

Схема вы описали в начале приятно - организовать все предпочтения под атрибутом для модели логически очень чистый - но для этого потребуются некоторые искажения. Почему бы не пойти с простым решением, которое может быть не таким красивым?

+0

Я закончил тем, что начал работать, для этого потребовалась таблица 'user_preferences' (' id', 'user_id'), а затем построены три сводные таблицы. Ответ подробно объясняется ниже. –