Основной Rails вопрос - Как создать новую запись в базе данных? - PullRequest
2 голосов
/ 11 декабря 2010

У меня есть следующие модели:

Product: name, shop_id (foreign key), brand_id (foreign key), price
Shop:    name
Brand:   name

Ассоциации:

Product: belongs_to :shop
         belongs_to :brand
Shop:    has_many   :products
         has_many   :brands,   :through => :products
Brand:   has_many   :products
         has_many   :shops,    :through => :products

Вопрос 1

Имеют ли эти ассоциации смысл?Не могли бы вы добавить другие ассоциации?

Вопрос 2

Я хотел бы предварительно заполнить базу данных в db/seeds.db.

Чтобы добавить Shop или Brand Я делаю:

Shop.create(:name => shop_name)
Brand.create(:name => brand_name)

Какой самый подходящий способ добавить Product?Мне действительно нужно вручную вводить значения shop_id и brand_id?Если магазин и торговая марка вновь созданного продукта еще не существуют, будут ли они автоматически добавлены в базу данных?

Ответы [ 2 ]

5 голосов
/ 11 декабря 2010

Общая идея с вашими ассоциациями заключается в следующем:

shop = Shop.create(:name => shop_name)
shop.brands << Brand.create(:name => brand_name)

Или наоборот. Вам не нужно вручную создавать модель соединения, если вы не хотите.

Редактировать: Ниже приведена демонстрация вашего комментария.

Настройка миграций.

$ ./script/rails g model Shop name:string
$ ./script/rails g model Brand name:string
$ ./script/rails g model Product brand_id:integer shop_id:integer
$ rm test/fixtures/*

$ rake db:migrate; rake db:test:prepare

Модели.

class Brand < ActiveRecord::Base
  has_many :products
  has_many :shops, :through => :products
end

class Shop < ActiveRecord::Base
  has_many :products
  has_many :brands, :through => :products
end

class Product < ActiveRecord::Base
  belongs_to :brand
  belongs_to :shop
end

Тест. Обратите внимание, что ни одна строка кода явно не создает продукт.

require 'test_helper'

class ShopTest < ActiveSupport::TestCase

  def test_brand_assignment_to_shop
    assert_equal 0, Product.count

    shop = Shop.create(:name => "Foo Shop")
    brand = Brand.create(:name => "Foo Brand")
    shop.brands << brand

    assert_equal 1, Product.count
    assert_equal shop.id, Product.first.shop_id
    assert_equal brand.id, Product.first.brand_id
  end
end



$ ruby -I./test test/unit/shop_test.rb 
Loaded suite test/unit/shop_test
Started
.
Finished in 0.029778 seconds.

1 tests, 4 assertions, 0 failures, 0 errors
1 голос
/ 11 декабря 2010

По мере того, как вы создаете модель продукта, в соответствии с этим ассоциации правы.

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

Для семян, я думаю, что да, вы вставили вручную shop_id и brand_id. Это можно сделать следующим образом:

@shop = Shop.create(:name => shop_name)
@brand = Brand.create(:name => brand_name)

Product.create(:shop_id => @shop.id , :brand_id => @brand.id)

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

Надеюсь, это может решить вашу проблему

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...