has_and_belongs_to_many:如何获得正确的关系? (JSON输出)

时间:2016-01-07 18:09:38

标签: ruby-on-rails json

我有item模型belongs_to product模型。 每个product has_and_belongs_to_many specification个模型:

class Product < ActiveRecord::Base
  has_many :items
  has_and_belongs_to_many :specifications
end

productsspecifications之间的关系保存在products_specifications JOIN表中:

  create_table "products_specifications", id: false, force: :cascade do |t|
    t.integer "product_id"
    t.integer "specification_id"
  end

enter image description here

每个specification has_and_belongs_to_many tags

class Specification < ActiveRecord::Base
  # Product Specifications (e.g. Color, Weight, Size, Brand, Product-Type)
  has_and_belongs_to_many :products
  has_and_belongs_to_many :tags # Tags = Spec Detail (e.g. blue, 100 gramm, 5x5x2.5 cm, Apple, Smartphone)
end

specifications_tags的加入表:

  create_table "specifications_tags", id: false, force: :cascade do |t|
    t.integer "specification_id"
    t.integer "tag_id"
  end

enter image description here

每个tag has_and_belongs_to_many specifications

class Tag < ActiveRecord::Base
  # Product Specifications Tag/Details (e.g. blue, 100 gramm, 5x5x2.5 cm, Apple, Smartphone)
  has_and_belongs_to_many :specifications    
end

我尝试使用JOIN表相关规范和JOIN表相关标签输出项目的产品,如下所示:

  def show
    item = Item.find(params[:id])

    render json: item.to_json(include: {
      product: {include: {specifications: {include: {tags: {}}}}}
    })
  end

这会输出正确的产品型号,但它包含数据库中的所有规格和所有标签,而不仅仅是相关的标签。 错误 JSON输出目前看起来像这样简化(对于属于“Apple iPhone 6智能手机”item的{​​{1}}):

product

目前我在数据库中只有两个"item":{"id":1,"product": {"id":1,"name":"Apple iPhone 6 Smartphone","specifications": [ {"id":1,"name":"Product Type","tags": [ {"id":1,"name":"Smartphone"}, {"id":1,"name":"Smartphone"} ] }, {"id":2,"name":"Brand","tags": [ {"id":2,"name":"Apple"}, {"id":4,"name":"Samsung"} ] }, {"id":3,"name":"Model","tags": [ {"id":3,"name":"iPhone 6"}, {"id":5,"name":"Galaxy A5"} ] } ] } } :“Apple iPhone 6 Smartphone”和“Samsung Galaxy A5 Smartphone”。您可以看到它输出所有产品的规格和标签,而不仅仅是products相关的产品。与“Apple iPhone 6智能手机”has_and_belongs_to_many相关的item正确 JSON输出如下所示:

product

编辑:

问题与JSON的输出方式无关。真正的问题是:

如何将标签正确地与相应产品的相应规格相关联?

2 个答案:

答案 0 :(得分:1)

这是与has_and_belongs_to_many关联的(思考)问题。我切换到has_many:通过关联,并创建了一个额外的模型/表:“product_specs”

  create_table "product_specs", force: :cascade do |t|
    t.integer  "product_id"
    t.integer  "specification_id"
    t.integer  "tag_id"
    t.integer  "creator_id"
    t.datetime "created_at",       null: false
    t.datetime "updated_at",       null: false
  end

现在我可以轻松地输出与JBuilder的正确关联(感谢@ kjmagic13指出来),如下所示:

json.extract! @item, :id, :condition, :user, :winner
  json.product do
    json.extract! @item.product, :name
    json.product_specs @item.product.product_specs do |spec|
      json.specification spec.specification, :id, :name
      json.tag spec.tag, :id, :name
  end
end

答案 1 :(得分:0)

你应该可以使用jbuilder。有点像:

# app/views/items/show.json.jbuilder
json.item do
    json.extract! @item, :id
    json.product do
        json.extract! @item.product, :name
        json.specifications @item.product.specifications do |spec|
            json.extract! spec, :name
            json.tags spec.tags, :id, :name
        end
    end
end

请务必在项目控制器的show方法中将item更改为实例变量@item