Ответ 1
Хорошо, я перечитал ваш вопрос, и я думаю, что у вас есть кое-что неправильное, поэтому вместо того, чтобы оставлять какие-либо комментарии к основному сообщению, я подумал, что я мог бы пойти на ответ, так что вот здесь.
Во-первых, ваши отношения неправильного типа и неправильного пути. Насколько я понимаю (и когда я реализую эти вещи в своей собственной работе), продукт принадлежит бренду - бренд может иметь несколько продуктов, но продукт может иметь только один бренд. Итак, сначала ваша схема БД - вы упомянули, что у вас есть таблица products
с обычными столбцами, а затем внешний ключ brand_id
. До сих пор так хорошо: это согласуется с тем, как я интерпретирую отношения.
Однако, тогда вы продолжаете показывать нам свою модель. У вас есть модель продукта как hasOne
Brand, но на самом деле она принадлежит бренду. Вы также не определяете обратную связь - вам нужны обе стороны, чтобы Laravel работал хорошо. В дополнение к этому ваше именование немного из-за ударов - возможно, это будет работать, но если мы будем следовать соглашениям Laravel, мы получим следующее:
В модели products
: Product.php
class Product extends Eloquent
{
public function brand()
{
return $this->belongsTo('Brand');
}
}
Теперь модель brands
: Brand.php
class Brand extends Eloquent
{
public function products()
{
return $this->hasMany('Product');
}
}
Хорошо, пока все хорошо. Вы заметите различные соглашения:
- Названия таблиц являются множественными (
products
,brands
) - Внешние ключи используют единственную (
brand_id
) - Названия моделей являются сингулярными и StudlyCase (поэтому
Product
для таблицыproducts
,Brand
для таблицыbrands
) - Свойство
$table
не нужно указывать, если вы следуете соглашениям Laravel (т.е. имя таблицы - это множественная версия snake_case модели classname - Вы должны определить отношение в обоих направлениях (по одному в каждой модели,
belongsTo
обратное значениеhasMany
, там также парыhasOne
/belongsTo
иbelongsToMany
/belongsToMany
) - Имена методов для получения отношения разумны - если вы ожидаете одного результата, сделайте его сингулярным (
Brand
вProduct
), если вы ожидаете, что множественные результаты сделают его множественным (products
вBrand
) - Используйте имена классов моделей в своих определениях отношений (
$this->hasMany('Brand')
not$this->hasMany('brands')
или любые другие варианты
Если вы придерживаетесь этих правил, ваши модели могут быть очень краткими, но очень мощными.
Теперь, что касается того, как вы фактически определяете реальные данные, я чувствую, что код, который вы опубликовали, может работать нормально (это действительно зависит от того, насколько умный Laravel за кадром), но, как я предложил в своем первом комментарии, d убедитесь, что я сохранил $brand
перед вызовом associate()
, просто чтобы Laravel не потерялся, чтобы понять, что делать. Поэтому я бы пошел на:
// create new brand and save it
$brand = new Brand;
$brand->name = "Brand 1";
$brand->save();
// create new product and save it
$product = new Product;
$product->name = "Product 1";
$product->description = "Description 1";
$product->brand()->associate($brand);
$product->save();
Таким образом, вы знаете, что у вас есть бренд в базе данных с его идентификаторами, уже определенными перед тем, как вы идете и используете его в отношениях.
Вы также можете определить отношения в обратном порядке, и это может быть меньше, чем мозг, чтобы сделать это:
// create new product and save it
$product = new Product;
$product->name = "Product 1";
$product->description = "Description 1";
$product->save();
// create new brand and save it
$brand = new Brand;
$brand->name = "Brand 1";
$brand->save();
// now add the product to the brand list of products it owns
$brand->products()->save($product);
Вам не нужно вызывать save()
на любой модели после этой последней строки, так как она автоматически принимает значение $brand
id
, помещает его в поле $product
brand_id
, а затем сохраняет $product
.
Для получения дополнительной информации см. документы о том, как это сделать: http://laravel.com/docs/eloquent#one-to-many
В любом случае, надеюсь, этот пост очистит хорошее количество ошибок в коде. Как я уже говорил выше, это соглашения, и вы можете пойти против них, но для этого вам нужно начать вводить дополнительный код, и он может быть совсем нечитаемым для других разработчиков. Я говорю, что если вы выберете определенную структуру, вы также можете следовать ее соглашениям.