ruby-on-rails - Ruby on Rails 中的交叉引用表

标签 ruby-on-rails ruby database activerecord

schema db

我有一个广告表,它与 ad_address 和 ad_copies 表具有 1:n 关系。 然后是类别和子类别表,其中类别与子类别表具有 1:n 关系,子类别表与广告表具有 1:n 关系。

因此,子类别表有一个名为 id_categories 的引用字段,广告表有一个名为 id_subcategories 的引用字段。

ads_address 和 ads_copy 表都有一个 ad_id 字段。

现在我一直忙于尝试从 json 文件(以前的数据库)中获取数据到新的 Rails 应用程序中。我发现这个先前数据库的模式包含一个单独的表,其中包含所有引用字段,即 id_categories、id_subcategories 和 ad_id 字段。

create_table "rel_anuncio", primary_key: ["id_anuncio", "id_categoria", "id_subcategoria"], force: :cascade, options: "ENGINE=MyISAM DEFAULT CHARSET=utf8" do |t|
  t.integer "id_anuncio", null: false
  t.integer "id_categoria", null: false
  t.integer "id_subcategoria", null: false
  t.integer "orden", null: false
end

下面是我如何播种我的广告记录(json 文件的表名是西类牙语):

if row['name'] == "categorias"

row["data"].each do |record|
  @cat = Category.create!(
    user_id: user.id,
    name: record["nombre"]
  )
end

elsif row['name'] == "subcategorias"

row["data"].each do |record|
  @subcat = Subcategory.create!(
    category_id: @cat.id,
    name: record["nombre"]
    )
end

row["data"].each do |record|
  @ad = Ad.create!(
    user_id: user.id,
    subcategory_id: @subcat.id,
    [..]
    )
end

我得到一个 "NoMethodError: undefined method 'id' for nil:NilClass""subcategory_id: @subcat.id",因为没有 subcategory_id链接到我意识到的广告记录,因为 subcategory_id 在不同的表中。

现在我知道必须有一种方法可以在散列中交叉引用这些 ID,这样您就可以看到哪些 ID 号属于哪条记录。例如,如果您有 id_subcategory: 3,那么它必须属于名称为“Wok Restaurant”且 ID 为:4 的广告记录。

我想在我的 Rails 应用程序中为我的广告记录植入正确的类别和子类别。

更一般地说,我想知道有人会如何处理在 railsapp 中导入具有与您自己的数据库不同架构的数据库的 json 文件。

这是 json 文件的示例(每个表格只有第一行):

[
  {"type":"header","version":"4.7.9","comment":"Export to JSON plugin for PHPMyAdmin"},
  {"type":"database","name":"qqx486"},
  {"type":"table","name":"anuncios","database":"qqx486","data":
    [
      {"id":"1","empresa":"Wok Bufet Gran Oriente","tel":"971 315 964","fax_principal":"","movil_principal":"","email_principal":"","web":"","facebook":"","horario_v_principal":"","horario_i_principal":"Abierto mediod\u00eda y noche","direccion_principal":"C\/ Jos\u00e9 Zornoza Bernabeu, 15, L2","poblacion_principal":"EIVISSA","activo":"no","tam_anuncio":"completa","twitter":"","link":"no","general":"no","isla":"ibiza","subtitulo":"","comentario":"","modificacion":"0000-00-00 00:00:00","promo1":"0","promo2":"0","instagram":"","tel2":"","tel3":"","tel4":"","movil2":"","movil3":"","movil4":""},
    ]
  }
  ,{"type":"table","name":"anuncios_direcciones","database":"qqx486","data":
    [
      {"id":"157","id_anuncio":"1","direccion":"C\/ Sant Jaume, 114","poblacion":"SANTA EUL\u00c0RIA","telefono":" 971 336 274","fax":"","movil":"","email":"","horario_i":"","horario_v":""},
    ]
  }
  ,{"type":"table","name":"anuncios_gps_a","database":"qqx486","data":
    [
      {"id":"1","id_anuncio":"22","lat":"38.9082100","lon":"1.4289690","accuracy":"10"},
    ]
  }
  ,{"type":"table","name":"anuncios_gps_b","database":"qqx486","data":
    [
      {"id_anuncio_direcciones":"459","id_anuncio":"1068","lat":"0.0000000","lon":"0.0000000","acc":"0"},
    ]
  }
  ,{"type":"table","name":"anuncios_textos","database":"qqx486","data":
    [
      {"id_anuncio":"1","id_idioma":"1","descripcion":""},
    ]
  }
  ,{"type":"table","name":"caracteristicas","database":"qqx486","data":
    [
      {"id":"1","nombre":"Jard\u00edn"},
    ]
  }
  ,{"type":"table","name":"caracteristicas_textos","database":"qqx486","data":
    [
      {"id_caracteristica":"1","id_idioma":"1","titulo":"Jard\u00edn"},
    ]
  }
  ,{"type":"table","name":"categorias","database":"qqx486","data":
    [
      {"id":"1","nombre":"RESTAURANTES Y ALIMENTACI\u00d3N","color":"","activo":"si","bdd":"guias","orden":"1","promoI":"0","promoF":"0","islas":"3"},
    ]
  }
  ,{"type":"table","name":"categorias_porsi","database":"qqx486","data":
    [
      {"id":"1","nombre":"RESTAURANTES Y ALIMENTACI\u00d3N","color":"","activo":"si","bdd":"guias","orden":"1","promoI":"0","promoF":"0"},
    ]
  }
  ,{"type":"table","name":"categorias_textos","database":"qqx486","data":
    [
      {"id_categoria":"1","id_idioma":"1","titulo":"RESTAURANTES Y ALIMENTACI\u00d3N","clave":""},
    ]
  }
  ,{"type":"table","name":"enlaces","database":"qqx486","data":
    [
      {"id":"1","nombre":"Digital Grafic Ibiza","web":"http:\/\/www.bestof.org"}
    ]
  }
  ,{"type":"table","name":"enlaces_textos","database":"qqx486","data":
    [
      {"id_enlace":"1","id_idioma":"1","descripcion":"Empresa en Ibiza"},
    ]
  }
  ,{"type":"table","name":"idiomas","database":"qqx486","data":
    [
      {"id":"1","nombre":"Espa\u00f1ol","self":"es","color":"F00"},
    ]
  }
  ,{"type":"table","name":"inmuebles","database":"qqx486","data":
    [
      {"id":"1","ref":"Roca Llisa","id_inmobiliaria":"91","tipo":"piso","estado":"","zona":"Santa Eulalia","sup_vivienda":"0","sup_parcela":"0","sup_terrazas":"0","plantas":"0","dormitorios":"3","banyos":"2","piscina":"no","parking":"no","entorno":"","precio":"380000","activo":"si"},
    ]
  }
  ,{"type":"table","name":"inmuebles_textos","database":"qqx486","data":
    [
      {"id_inmueble":"1","id_idioma":"1","titulo":"Roca Llisa","descripcion":"Apartamento d\u00faplex, cocina, sal\u00f3n\/comedor, 2 terrazas, preciosas vistas al mar, piscina y paddle tenis comunitarios."},
    ]
  }
  ,{"type":"table","name":"playas","database":"qqx486","data":
    [
      {"id":"1","nombre":"PLATJA DE TALAMANCA","longitud":"900","orientacion":"SE","google":"https:\/\/www.google.es\/maps\/place\/Cala+Talamanca\/@38.9132677,1.4565971,16z\/data=!4m2!3m1!1s0x1299414743b6e207:0xe628e2f006419c0d","cnauticas":"38\u00b055\u201900.8\u201dN 1\u00b027\u201916.8\u201dE","municipio":"Eivissa","activo":"si","orden":"0"},
    ]
  }
  ,{"type":"table","name":"playas_textos","database":"qqx486","data":
    [
      {"id_playa":"1","id_idioma":"1","breve":"Playa de arena fina a pocos minutos a pie de Marina Botafoch y a 1,8 km. del centro de la ciudad de Eivissa.","descripcion":"Se trata de una bah\u00eda cerrada, poco profunda, ideal para el ba\u00f1o sin ning\u00fan peligro y muy bien protegida por los vientos. Gran variedad en restaurantes, bares y chiringuitos, incluso algunos est\u00e1n abiertos todo el a\u00f1o. Existe una pasarela de madera a lo largo de casi toda la playa. Se realizan cursos para iniciarse en deportes n\u00e1uticos como el catamar\u00e1n, kayak y windsurf.","servicios":"Restaurantes y chiringuitos \u2013 Hoteles \u2013 Alquiler de tumbonas y sombrillas \u2013 Deportes acu\u00e1ticos \u2013 Duchas y WC p\u00fablicos \u2013 Acceso minusv\u00e1lidos \u2013 Parking gratis \u2013 Transporte p\u00fablico.","llegar":"En coche, en autob\u00fas de l\u00ednea regular o en una barquita que va del puerto de Eivissa hasta Botafoch, y de ah\u00ed puede ir andando llegando en pocos minutos."},
    ]
  }
  ,{"type":"table","name":"promo","database":"qqx486","data":
    [
      {"id":"1","idioma":"1","empresa_id":"943","titulo":"10% Descuento","tituloCR":"8","tituloCG":"8","tituloCB":"8","tituloFS":"20","texto1":"7 horas de fiesta y mucho m\u00e1s","texto1CR":"255","texto1CG":"255","texto1CB":"255","texto1FS":"20","fondo1CR":"255","fondo1CG":"43","fondo1CB":"227","fondo1CA":"90","texto2":"","foto1":"","foto2":"","code":"C\u00f3digo: Isla Blanca","tiempo1":"0000-00-00 00:00:00","tiempo2":"0000-00-00 00:00:00","activo":"2","status":"1","orden":"1"},
    ]
  }
  ,{"type":"table","name":"rel_anuncio","database":"qqx486","data":
    [
      {"id_anuncio":"814","id_categoria":"7","id_subcategoria":"81","orden":"37"},
    ]
  }
  ,{"type":"table","name":"rel_guias","database":"qqx486","data":
    [
      {"id_anuncio":"7","id_guia":"1"},
    ]
  }
  ,{"type":"table","name":"rel_inmuebles","database":"qqx486","data":
    [
      {"id_inmueble":"1","id_caracteristica":"2"},
    ]
  }
  ,{"type":"table","name":"subcategorias","database":"qqx486","data":
    [
      {"id":"1","id_categoria":"1","nombre":"Restaurantes","color":"","activo":"si","orden":"1","promoI":"0","promoF":"0","islas":"3"},
    ]
  }
  ,{"type":"table","name":"subcategorias_porsi","database":"qqx486","data":
    [
      {"id":"1","id_categoria":"1","nombre":"Restaurantes","color":"","activo":"si","orden":"1","promoI":"0","promoF":"0"},
    ]
  }
  ,{"type":"table","name":"subcategorias_textos","database":"qqx486","data":
    [
      {"id_subcategoria":"1","id_idioma":"1","nombre":"Restaurantes","clave":"restaurantes, pizzer\u00edas, los productos de alimentaci\u00f3n, almuerzos, cenas, fiestas, c\u00f3cteles, cocktails, comen, comer, beber, las cocinsa mediterr\u00e1neas, barras, comedores, comiento, sitios para comer, restaurantes especializados en bistecs, el alimento japon\u00e9s, comida japonesa, el alimento espa\u00f1ol, comida espa\u00f1ola, el alimento italiano, comida italiana, parrillas, la cocina francesa, el alimento alem\u00e1n, comida alemana, comidas, licores, mariscos, el alimento asi\u00e1tico, comida asi\u00e1tica, pescados, mariscos, camarones, gambas, tabernas,"},
    ]
  }
  ,{"type":"table","name":"version","database":"qqx486","data":
    [
      {"id":"32"}
    ]
  }
]

最佳答案

看起来 AdSubcategory 具有多对多关系。所以 rel_anuncio 是建立关系的中间表。

由于 json 的行与您创建记录所需的顺序不同。

而是尝试首先创建 Ads,然后是 Categories,最后是 Subcategories

json_ads = parsed_json.find { |table| table['name'] == 'anuncios' }
ads = {}

json_ads['data'].each do |ad|
  ads[ad['id']] = Ad.create(
    [... ad fields]
  )
end

类别也是如此:

json_categories = parsed_json.find { |table| table['name'] == 'categorias' }
categories = {}

json_categories['data'].each do |category|
  categories[category['id']] = Category.create(
    [... category fields]
  )
end

现在您已经创建了 Subcategories,您有 HashCategories 来引用它们:

json_subcategories = json.find { |table| table['name'] == 'rel_anuncio' }
subcategories = {}

json_subcategories['data'].each do |subcategory|
  subcategories[subcategory['id']] = Subcategory.create(
    category: categories[subcategory['id_categoria'],
    [... ad fields]
  )
end

rel_anuncio 信息将取决于您如何实现关系。

希望对您有所帮助。

关于ruby-on-rails - Ruby on Rails 中的交叉引用表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50150406/

相关文章:

sql - 有没有办法在不执行未知数据库查询的情况下获取类型/名称?

mysql - 从 rails 中的另一个对象创建一个对象

Ruby:在某些命名空间的上下文中工作

ruby - 在 Ruby 中组合 3 个并行数组的最佳和最快方法是什么

ruby-on-rails - 如何停止 rails nginx-passenger 应用程序?

MongoDB - 通过数组中多个对象的相同字段查询文档

c - 每条记录上次更新的记录时间戳

ruby-on-rails - Heroku Assets 预编译

ruby-on-rails - 如何将 Digital Ocean 应用程序文件夹复制到本地机器?

ruby-on-rails - Rails 4.2 Postgres 9.4.4 statement_timeout 不起作用