Хорошо, я перечитал ваш вопрос, и я думаю, что у вас есть кое-что неправильное, поэтому вместо того, чтобы оставлять какие-либо комментарии к основному сообщению, я подумал, что могу ответить на вопрос.
Прежде всего, ваши отношения неправильного типа и неправильного пути. Насколько я понимаю (и когда я реализую эти вещи в своей собственной работе), продукт принадлежит бренду - бренд может иметь несколько продуктов, но продукт может иметь только один бренд. Итак, сначала ваша схема БД - вы упомянули, что у вас есть таблица products
с обычными столбцами, а затем внешний ключ brand_id
. Пока все хорошо: это согласуется с тем, как я интерпретирую отношения.
Тем не менее, вы затем продолжаете показывать нам свою модель. У вас есть модель продукта как hasOne
Бренд - но на самом деле это относится к бренду. Вы также не определяете обратную связь - вам нужны обе стороны, чтобы 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 модели classnamename
- Вы должны определить отношения в обоих направлениях (одна в каждой модели, обратная
belongsTo
«s является hasMany
, есть также пары hasOne
/belongsTo
и belongsToMany
/belongsToMany
)
- Имена методов для извлечения отношений являются разумным - если вы ожидаете одного результата, сделать его единственного числа (
brand
в Product
), если вы ожидаете несколько результатов сделать это множественное число (products
в Brand
)
- Используйте модель имен классов в определениях отношений (
$this->hasMany('Brand')
не $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's list of products it owns
$brand->products()->save($product);
Вам не нужно звонить save()
на любой модели после этой последней строки, так как он автоматически примет значение $brand
id
, поместите его в поле $product
brand_id
, а затем сохраните $product
.
Для получения дополнительной информации смотрите документацию о том, как сделать эти отношения вставки: http://laravel.com/docs/eloquent#one-to-many
Во всяком случае, надеюсь, этот пост проясняет хорошую сумму, что было не так с вашим кодом. Как я уже говорил выше, это соглашения, и вы можете пойти против них, но для этого вам нужно начать вводить дополнительный код, и он может быть совсем нечитаемым для других разработчиков. Я говорю, что если вы выберете определенную структуру, вы также можете следовать ее соглашениям.
Возможно, вам придется сохранить бренд перед тем, как вызывать '$ product-> associate();' Имейте это в виду. – alexrussell
Только что замеченный в вашем сообщении вы говорите, что вы «думаете, что модель брендов должна иметь только« защищенные таблицы »=« бренды »,« строка », но это не так, насколько я знаю. Я уверен, что у модели должен быть «public function product() {return $ this-> belongsTo ('Product'); } ', таким образом вызов' associate() 'в модели $ products может заполнить поле' product_id' модели 'Brands'. Я не на 100% с 'hasOne', но это определенно, как это происходит с' hasMany', и это то же самое в обратном отношении (т. Е. Модель имеет столбец 'foreign_id'). – alexrussell