Подтвердить что ты не робот

Невозможно получить красноречие для автоматического создания объединений

Извините заранее, если ответ на мой вопрос очевиден. Я проделал свою должную осмотрительность в исследовании этой темы, прежде чем я разместил здесь.

Большая часть моего опыта работы с картой исходит от использования CodeIgniter, поэтому у меня никогда не было практического опыта использования ORM. (У CI есть некоторые готовые ORM-решения, но я их никогда не использовал.)

Я хотел бы использовать встроенную функциональность ORM в Laravel Rloquent ORM для автоматического объединения таблиц турниров и стран вместе при выполнении запроса и возврата набора данных, который также включает данные о турнире как соответствующие данные по стране.

То есть, я хочу, чтобы Eloquent автоматически распознавал отношения внешнего ключа, чтобы я мог просто запустить запрос (например, Tournament:: with ('Country') → all()), который вернет весь набор турниров и данные по стране.

Пожалуйста, остановите меня прямо сейчас, если я использую Eloquent таким образом, чтобы он никогда не предназначался для использования! Моя путаница может быть больше о том, как я пытаюсь смять несостоятельное решение, а не синтаксис или ошибку кодирования.

Запрос, который я хотел бы реплицировать в "Красноречивый"

SELECT * FROM tournaments LEFT JOIN countries ON tournaments.country_id = countries.id

Ожидаемый результат в PHP

Я ожидаю получить массив объектов турнира (в PHP), где будет выглядеть один объект турнира:

  • tournaments.id
  • tournaments.year
  • tournaments.country_id
  • tournaments.created_at
  • tournaments.updated_at
  • countries.id
  • countries.code
  • countries.name
  • countries.url
  • countries.created_at
  • countries.updated_at

Неудачные Attemps, которые я сделал до сих пор

Я выполнил все эти попытки в методе фиктивного контроллера и вывел результат в виде форматированной строки в профилировщик.

Ошибка при попытке # 1:

PHP-код в фиктивном контроллере:

$tournaments = Tournament::with('Country')->all();

Создает следующий запрос:

SELECT * FROM `tournaments`

Результат # 1 возвращает:

Массив, содержащий объекты турнира, которые включают только столбцы в таблице турниров.

Не удалось выполнить попытку # 2

PHP-код в фиктивном контроллере:

$tournaments = Tournament::with('Country')->first();

Вызывает следующую ошибку:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'tournament_id' in 'where clause'

SQL: SELECT * FROM `countries` WHERE `tournament_id` IN (?)

Bindings: array (
0 => '1',
)

Другие неудачные попытки

Я пробовал различные комбинации соглашений об именах (например, столбцы, таблицы и т.д.) безрезультатно. Я также попытался создать запрос в Fluent, который работал нормально, но мне потребовалось указать соединения, которых я пытаюсь избежать.

Моя окружающая среда

  • PHP: 5.3.13
  • MySQL: 5.1.53
  • Laravel: 3.2.3

Связь между таблицами

  • отношения "один-к-одному"
  • В турнире должна быть страна (есть ограничение внешнего ключа, чтобы обеспечить ее соблюдение).
  • Страна может принадлежать многим другим отношениям (например, участник, не показан здесь, имеет страну рождения).

Таблица стран

CREATE TABLE `countries` (                                                                                                                                                                                                                 
`id` int(11) NOT NULL AUTO_INCREMENT,                                                                                                                                                                                                       
`code` varchar(4) NOT NULL,                                                                                                                                                                                                                 
`name` varchar(25) NOT NULL,                                                                                                                                                                                                                
`url` varchar(25) NOT NULL,                                                                                                                                                                                                                 
`created_at` datetime NOT NULL,                                                                                                                                                                                                             
`updated_at` datetime NOT NULL,                                                                                                                                                                                                            
PRIMARY KEY (`id`),                                                                                                                                                                                                                        
UNIQUE KEY `countries_code_unique` (`code`),                                                                                                                                                                                               
KEY `countries_url_index` (`url`)                                                                                                                                                                                                          
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=latin1

Таблица турниров

CREATE TABLE `tournaments` (                                                                                                                                                                                                             
`id` int(11) NOT NULL AUTO_INCREMENT,                                                                                                                                                                                                       
`year` int(11) NOT NULL,                                                                                                                                                                                                                    
`country_id` int(11) NOT NULL,                                                                                                                                                                                                              
`created_at` datetime NOT NULL,                                                                                                                                                                                                             
`updated_at` datetime NOT NULL,                                                                                                                                                                                                             
PRIMARY KEY (`id`),                                                                                                                                                                                                                         
UNIQUE KEY `tournaments_year_unique` (`year`),                                                                                                                                                                                             
KEY `tournaments_country_id_foreign` (`country_id`),                                                                                                                                                                                      
CONSTRAINT `tournaments_country_id_foreign` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON UPDATE CASCADE                                                                                                                  
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=latin1

Страны Модель (countries.php)

class Country extends Eloquent {
    public static $timestamps = true;
    public static $table = 'countries';
}

Модель турниров (tournament.php)

class Tournament extends Eloquent {
    public static $timestamps = true;

    public function country()
    {
        return $this->has_one('Country');
    }
}
4b9b3361

Ответ 1

Ясно, что with('Country') или with('Country') не отличается от того, что ему удалось получить следующую ошибку:

Column not found: 1054 Unknown column 'tournament_id' in 'where clause'

SQL: SELECT * FROM `countries` WHERE `tournament_id` IN (?)

Неправильно то, как определяется связь: Турнир должен иметь страну, которая должна принадлежать стране, и не имеет одной страны. Итак, чтобы решить это изменение, отношение к

public function country()
{
    return $this->belongs_to('Country');
}

Ответ 2

Согласно документам Eloquent:

Примечание. Все методы, доступные в построителе запросов, также доступны при запросе моделей Eloquent.

Итак, имея в виду что-то вроде:

DB::table("tournament")->join("countries","tournaments.country_id","=","countries.id")->get();

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

UPDATE:

Да, используя методы создания запросов Eloquent, вы можете:

Tournament::join("countries","tournaments.country_id","=","countries.id")->get();

Это вернет модель турнира, которая включает в себя поля обеих таблиц.

НТН

Ответ 3

В предложении 'with' запрашивается "Страна", но ваш код объявляет его "страной".

Итак, если:

$tournaments = Tournament::with('Country')->all();

Be:

$tournaments = Tournament::with('Country')->all();

Потому что в вашей модели турниров вы определили это как:

public function country()
{
    return $this->has_one('Country');
}

Помогает ли это изменение?

Ответ 4

Вы должны убедиться, что ваши отношения объявлены в вашей модели турнира:

public function country() {
    return $this->has_one('Country');
}

Кроме того, вам придется объявить обратное в вашей модели страны:

public function tournament() {
    return $this->belongs_to('Tournament');
}

На этом этапе вы можете получить доступ к объекту турнира, связанному с объектом страны, следующим образом:

$tournaments = Tournament::with('country')->all();
foreach ($tournaments as $tournament) {
    echo $tournament->country;
}

Сообщите мне, отобразите ли вы каждую соответствующую страну на турнир.