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

Laravel: красноречивый пример вставить данные в базу данных

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

Я прочитал эту статью и теперь понимаю некоторые основы.

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

Продукты: id (PK), имя, описание, brand_id бренды: id (PK), имя

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

Короче. Я хочу, чтобы brand.id внутри products.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');
    }
  }

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

4b9b3361

Ответ 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

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