ruby-on-rails 通过Rails ActiveRecord查询创建哈希数组的嵌套哈希

rn0zuynd  于 2022-11-19  发布在  Ruby
关注(0)|答案(1)|浏览(171)

我使用的是rails 7,我需要创建这个数据结构。
给定产品的可用选项组合的“树”结构。

{
  "option": "color",
  "values": {
    "red": {
      "option": "size",
      "values": {
        "S": {
          "option": "material",
          "values": {
            "cotton": {
              "sku": "shirt-red-s-cotton"
            }
          },
        },
        "M": { ... },
        "L": { ... },
      }
    },
    "green": { ... },
    "blue": { ... }
  }
}

我有下一个模式:

ActiveRecord::Schema[7.0].define(version: 2022_11_04_214231) do
  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "items", force: :cascade do |t|
    t.bigint "product_id", null: false
    t.json "p_options"
    t.string "sku"
    t.integer "stock"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["product_id"], name: "index_items_on_product_id"
    t.index ["sku"], name: "index_items_on_sku", unique: true
  end

  create_table "product_option_lists", force: :cascade do |t|
    t.bigint "product_id", null: false
    t.bigint "product_option_id", null: false
    t.string "option"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["product_id"], name: "index_product_option_lists_on_product_id"
    t.index ["product_option_id"], name: "index_product_option_lists_on_product_option_id"
  end

  create_table "product_options", force: :cascade do |t|
    t.string "option"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["option"], name: "index_product_options_on_option", unique: true
  end

  create_table "products", force: :cascade do |t|
    t.string "name"
    t.boolean "active"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["name"], name: "index_products_on_name", unique: true
  end

  add_foreign_key "items", "products"
  add_foreign_key "product_option_lists", "product_options"
  add_foreign_key "product_option_lists", "products"
end

我相信,ActiveRecord可以使用以下方法获取开始创建此数据结构所需的所有信息:

Item.where(product_id: <some_id>)

# or maybe mapping it to get only the options of the product

Item.where(product_id: <some_id>).map{ |item| item.p_options }

第二个查询返回如下所示的值:(根据我使用的种子数据)

[{ "Size" => "S", "Color"=>"Red"   , "Material"=>"Cotton"},
 { "Size" => "S", "Color"=>"Green" , "Material"=>"Silk"},
                     -----------
 { "Size" => "XL", "Color" => "Blue", "Material"=> "Cotton"}]

我也认为这可以通过对每个键的可能值进行递归来实现,但是我仍然不理解哈希结构的递归。
也许我已经做的这个端点是有用的。它为给定的产品返回这个数据结构。

[
  { "option": "color", "values": ["Red","Green", "Blue"]},
  { "option": "size", "values": ["S", "M", "L"]},
  ...
]
mpbci0fu

mpbci0fu1#

我创建了产品选项,用于使用递归处理所有可用选项
这是我用递归创建的一个演示

create_table "product_options", force: :cascade do |t|
 t.string "option_label"
 t.string "option_text"
 t.string "value_label"
 t.bigint "product_id", null: false
 t.datetime "created_at", null: false
 t.datetime "updated_at", null: false
 t.bigint "parent_id"
 t.index ["parent_id"], name: "index_product_options_on_parent_id"
end

create_table "products", force: :cascade do |t|
 t.string "name"
 t.boolean "active"
 t.datetime "created_at", null: false
 t.datetime "updated_at", null: false
 t.index ["name"], name: "index_products_on_name", unique: true
end

add_foreign_key "product_options", "product_options", column: "parent_id"
add_foreign_key "product_options", "products"

class ProductOption < ApplicationRecord
  belongs_to :parent, optional: true, class_name: 'ProductOption'
  has_many :options, class_name: 'ProductOption', foreign_key: :parent_id, dependent: :destroy  
end

def index
  @product_options = ProductOption.first
end

index.html.erb

<%= @product_options.option_label %>:<%= @product_options.option_text %></br>
<%= render partial:'partial', locals:{ option: @product_options.options } %>

_部分.html.erb

<% option.each_with_index do |single, index| %>
 <%= "#{single.option_label}:#{single.option_text}" if single.option_label.present? %> <br>
  <%= "#{single.value_label}:" %> <br>
  <%= render partial: 'partial', locals: {option: single.options}  %><br>
<% end%>

种子数据添加位置:https://gist.github.com/hemangini-gohel/c1fff10f60f51390c60de73fd3d1b31b

相关问题