2014-02-16 2 views
14

Прошу простить об этом, но я пришел из кодаIgniter и очень усложнил понимание красноречивой установки модели. Это новый способ работы с моделями для меня.laravel: красноречивый пример вставить данные в базу данных

Я прочитал this article и понимаю некоторые основы сейчас.

У меня есть следующий пример. У меня есть продукт, который имеет много атрибутов, но релевантным является название бренда и продукта. (См следующих примеров таблиц)

продуктов: идентификатор (PK), название, описание, Brand_ID брендов ID (PK), имя

Теперь здесь возникает проблема. Я знаю, что могу создать новый бренд, и я знаю, как я могу создать новый продукт. Однако у меня нет qlue, как соединить эти два вместе. Вот какой код у меня есть сейчас. Я хочу создать новый продукт и автоматически заполнить таблицу брендов. Это часть контроллера прямо сейчас.

Вкратце. Я хочу, чтобы марки. Внутри изделия.brand_id

$product = new Products; 
    $product->name = "product1"; 
    $product->description = "description1"; 

    $brand = new Brands; 
    $brand->name = "brand1" 
    $product->brand()->associate($brand); 

    $brand->save(); 
    $product->save(); 

Чтобы сделать его более понятным. У меня 2 модели. продуктов и брендов. Однако мне непонятно, что должно быть в модели. Это моя модель текущих продуктов. Я думаю, что модель брендов должна иметь только защищенные $ table = «бренды»; линии внутри класса модели.

class Products extends Eloquent { 

    protected $table = 'products'; 

    public function brand() 
    { 
     return $this->hasOne('brands'); 
    } 
    } 

Может кто-нибудь объяснить мне, что я делаю неправильно. Я не могу найти хороший учебник, как работать с вставкой данных внутри красноречивых моделей с отношениями. Большинство учебных пособий посвящены отображению данных.

+0

Возможно, вам придется сохранить бренд перед тем, как вызывать '$ product-> associate();' Имейте это в виду. – alexrussell

+0

Только что замеченный в вашем сообщении вы говорите, что вы «думаете, что модель брендов должна иметь только« защищенные таблицы »=« бренды »,« строка », но это не так, насколько я знаю. Я уверен, что у модели должен быть «public function product() {return $ this-> belongsTo ('Product'); } ', таким образом вызов' associate() 'в модели $ products может заполнить поле' product_id' модели 'Brands'. Я не на 100% с 'hasOne', но это определенно, как это происходит с' hasMany', и это то же самое в обратном отношении (т. Е. Модель имеет столбец 'foreign_id'). – alexrussell

ответ

40

Хорошо, я перечитал ваш вопрос, и я думаю, что у вас есть кое-что неправильное, поэтому вместо того, чтобы оставлять какие-либо комментарии к основному сообщению, я подумал, что могу ответить на вопрос.

Прежде всего, ваши отношения неправильного типа и неправильного пути. Насколько я понимаю (и когда я реализую эти вещи в своей собственной работе), продукт принадлежит бренду - бренд может иметь несколько продуктов, но продукт может иметь только один бренд. Итак, сначала ваша схема БД - вы упомянули, что у вас есть таблица 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'); 
    } 
} 

хорошо до сих пор так хорошо. Вы увидите различные конвенции:

  1. Имена таблиц во множественном числе (products, brands)
  2. Внешние ключи используют особые (brand_id)
  3. Названия моделей являются особыми и StudlyCase (так Product для таблицы products, Brand для таблицы brands)
  4. Свойство $table не обязательно указывать, если вы следуете соглашениям Laravel (например, имя таблицы - это множественная версия snake_case модели classnamename
  5. Вы должны определить отношения в обоих направлениях (одна в каждой модели, обратная belongsTo «s является hasMany, есть также пары hasOne/belongsTo и belongsToMany/belongsToMany)
  6. Имена методов для извлечения отношений являются разумным - если вы ожидаете одного результата, сделать его единственного числа (brand в Product), если вы ожидаете несколько результатов сделать это множественное число (products в Brand)
  7. Используйте модель имен классов в определениях отношений ($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() на любой модели после этой последней строки, так как он автоматически примет значение $brandid, поместите его в поле $productbrand_id, а затем сохраните $product.

Для получения дополнительной информации смотрите документацию о том, как сделать эти отношения вставки: http://laravel.com/docs/eloquent#one-to-many

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

+1

Не знаете, кто это проигнорировал, но почему? Я думал, что мой ответ был довольно проработан и отвечает на этот вопрос, а также предлагает улучшения исходного кода (поскольку он был немного грязным и, возможно, даже не работал так, как было). Очень рад слышать критику. – alexrussell

+0

Это именно тот ответ, который я искал. Это сработало, а также важно: я получил яркий пример соглашения об именах. Thnx – Klaas

+0

Нет проблем. Бесплатно бесплатно повышать также, чтобы отменить работу того, кто его ниспровергал, если хотите. – alexrussell

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