首页 > 解决方案 > Rails 和 Activerecord,更好的方法来统一几个对象来绘制比较表

问题描述

我必须在我的表中的一些记录之间绘制一个比较表。

这些是我的课。

class Product < ApplicationRecord

  has_many :product_features
  has_many :features, through: :product_features
  has_many :product_features_groups
  has_many :feature_groups

end 

这是我的产品类,我存储产品的地方。例如,我的产品是智能手机。

class Feature < ApplicationRecord
  has_many :products, through: :product_features
  has_many :product_features
end

这是我的要素类,我在其中添加要素名称,例如“分辨率”

class ProductFeature < ApplicationRecord

  belongs_to :feature
  belongs_to :product
  belongs_to :product_features_group
  has_one :feature_group, through: product_features_group

  default_scope { order(order: :desc) }
end

这是我的产品和功能之间的连接表,我在其中存储每个产品的分辨率值。

然后我有另外两个模型来定义功能组,例如“显示”。

class ProductFeaturesGroup < ApplicationRecord

  belongs_to :product
  belongs_to :feature_group
  has_many :product_features

  default_scope { order(order: :desc) }

end

class FeatureGroup < ApplicationRecord

end

基本上我的智能手机有一些功能组(显示、连接、设计),对于每个功能组我都有几个功能。

我有两个或更多的产品要比较,我必须画一张表。如果每个产品都具有相同的功能组和相同的功能,这将非常容易,但这不是我的情况。

我必须找到一种方法来统一我的产品。

我开始使用从我的比较视图传递的 IDS 数组来比较我的产品。

products = Products::Product.includes( { product_features_groups: [ { product_features: [:feature, :product_features_group] }] }).where(id: params["products"])

然后我想映射 products 数组以收集每个 product_features,然后再次映射以创建一个哈希数组,其中我有我的产品中存在的每个功能和每个功能组进行比较。然后我添加唯一的,因为当然我必须删除存在于多个产品中的重复项、特征......

compared_products = products.map{|p| p.product_features}.flatten.map{ |f| {feature_id: f.feature_id, features_group_id: f.feature_group.id, feature_name: f.feature.name, group_name: f.feature_group.name}}.uniq

现在的结果是这样的:

   {:feature_id=>5214, :features_group_id=>148, :feature_name=>"Materiale della scocca", :group_name=>"Design"},
 {:feature_id=>11025, :features_group_id=>148, :feature_name=>"Colore cinturino", :group_name=>"Design"},
 {:feature_id=>1721, :features_group_id=>27, :feature_name=>"Durata batteria", :group_name=>"Gestione energetica"},
 {:feature_id=>1025, :features_group_id=>184, :feature_name=>"Microfono incorporato", :group_name=>"Prestazione"},
 {:feature_id=>7610, :features_group_id=>5, :feature_name=>"Tipo di vetro", :group_name=>"Display"},
 {:feature_id=>3239, :features_group_id=>12, :feature_name=>"Wi-Fi", :group_name=>"Connettività"},
 {:feature_id=>2433, :features_group_id=>184, :feature_name=>"Altoparlanti incorporati", :group_name=>"Prestazione"},
 {:feature_id=>1208, :features_group_id=>12, :feature_name=>"Versione Bluetooth", :group_name=>"Connettività"}

然后我按组名分组

compared_products.group_by{|h| h[:group_name]}.values 

[[{:feature_id=>432, :features_group_id=>12, :feature_name=>"Standard Wi-Fi", :group_name=>"Connettività"},
  {:feature_id=>23798, :features_group_id=>12, :feature_name=>"Porta USB", :group_name=>"Connettività"},
  {:feature_id=>3239, :features_group_id=>12, :feature_name=>"Wi-Fi", :group_name=>"Connettività"},
  {:feature_id=>1208, :features_group_id=>12, :feature_name=>"Versione Bluetooth", :group_name=>"Connettività"},
  {:feature_id=>4163, :features_group_id=>12, :feature_name=>"Connessione cuffia", :group_name=>"Connettività"}],
 [{:feature_id=>6702, :features_group_id=>185, :feature_name=>"Cardiofrequenzimetro", :group_name=>"Caratteristiche"},
  {:feature_id=>9731, :features_group_id=>185, :feature_name=>"Accelerometro", :group_name=>"Caratteristiche"},
  {:feature_id=>9732, :features_group_id=>185, :feature_name=>"Giroscopio", :group_name=>"Caratteristiche"},
  {:feature_id=>16407, :features_group_id=>185, :feature_name=>"Motore per la vibrazione", :group_name=>"Caratteristiche"},
  {:feature_id=>4277, :features_group_id=>185, :feature_name=>"Gestione dati personali", :group_name=>"Caratteristiche"},
  {:feature_id=>8720, :features_group_id=>185, :feature_name=>"Sensore luce ambientale", :group_name=>"Caratteristiche"}],
 [{:feature_id=>2172, :features_group_id=>184, :feature_name=>"Radio FM", :group_name=>"Prestazione"},
  {:feature_id=>8956, :features_group_id=>184, :feature_name=>"Sistema operativo mobile supportato", :group_name=>"Prestazione"},
  {:feature_id=>3233, :features_group_id=>184, :feature_name=>"Sistema operativo incluso", :group_name=>"Prestazione"},
  {:feature_id=>730, :features_group_id=>184, :feature_name=>"Tipi schede di memoria", :group_name=>"Prestazione"},
  {:feature_id=>1013, :features_group_id=>184, :feature_name=>"Produttore processore", :group_name=>"Prestazione"},
  {:feature_id=>47, :features_group_id=>184, :feature_name=>"Modello del processore", :group_name=>"Prestazione"},
  {:feature_id=>6089, :features_group_id=>184, :feature_name=>"Numero di core del processore", :group_name=>"Prestazione"},
  {:feature_id=>1025, :features_group_id=>184, :feature_name=>"Microfono incorporato", :group_name=>"Prestazione"},
  {:feature_id=>2433, :features_group_id=>184, :feature_name=>"Altoparlanti incorporati", :group_name=>"Prestazione"},
  {:feature_id=>8074, :features_group_id=>184, :feature_name=>"Fotocamera integrata", :group_name=>"Prestazione"}],
 [{:feature_id=>7605, :features_group_id=>148, :feature_name=>"Materiale cinturino", :group_name=>"Design"},
  {:feature_id=>17541, :features_group_id=>148, :feature_name=>"Misura del polso", :group_name=>"Design"},
  {:feature_id=>9397, :features_group_id=>148, :feature_name=>"Forma", :group_name=>"Design"}...

现在,我的结果按功能组分组,我拥有每个功能组和我的产品数组的每个功能,我可以使用它来创建我的表格行。然后,对于每个产品,如果该功能存在,我可以在单元格中插入值,如果该功能不存在,我可以在单元格中留一个空格。

有没有一种不那么混乱的方法来处理这样的事情?有什么我可以改进的吗?

标签: ruby-on-rails

解决方案


推荐阅读