我正在开发一个新的rails项目,在这个项目中我有产品和产品类别。
所以这些类别彼此非常不同,仅举几例,船,房屋,汽车。
汽车类别可能有“Mph”,“Model”,“Brand”,“Year”等标准。房屋类别将包括“房间”,“年”,“城市”,“邮政编码”等。
我希望这是非常动态的,这样我就可以添加/删除标准,并在后端面板中添加/删除类别。
现在我的问题是,我一直在玩这个,我无法弄清楚这个概念的逻辑,我已经尝试了一些解决方案,但是它们非常奇怪且非常低效。也许一些铁杆导轨编码器可以给我一个暗示,如何解决这个难题?
所以我能提出的最佳解决方案是:
四种模式:
_______________________
| Product.rb |
-----------------------
| id | integer |
-----------------------
| category_id | integer |
-----------------------
| Title | string |
-----------------------
| Description | text |
-----------------------
_______________________
| Category.rb |
-----------------------
| id | integer |
-----------------------
| Title | string |
-----------------------
| Description | text |
-----------------------
_______________________
| Criteria.rb |
-----------------------
| id | integer |
-----------------------
| category_id | integer |
-----------------------
| Name | string |
-----------------------
| Default | string |
-----------------------
| Description | text |
-----------------------
_______________________
| ProductInfo.rb |
-----------------------
| id | integer |
-----------------------
| product_id | integer |
-----------------------
| Name | string |
-----------------------
| Value | text |
-----------------------
如何连接:
Criteria.rb is connected to Category.rb with a category_id and has_many/belongs_to relation
Product.rb is connected to Category.rb with a category_id and has_many/belongs_to relation
ProductInfo.rb is connected to Product.rb with a product_id and has_many/belongs_to relation.
Category.rb is the heart og this solution. The category model, both have many products and criterias.
它应该如何运作,实际上:
In the show category page, i would first print out all the criterias for the given category.
Afterwards i would make a @products.each do |product|.
In the @products.each block, i would make a @category.criterias.each do |criteria|.
In the @category.criterias.each block, i would then run something like product.productinfos.where(:name => criteria.name).
And then run it one by one.
结论,这个解决方案确实有效,但我怀疑它是最好的解决方案。它将产生极大的加载时间,具有高流量和大量数据。我将需要编写非常奇怪和不可读的代码。
这是一个相当长的问题,它可能会非常令人困惑,所以如果有什么请说,请说。此外,我已经在Stackoverflow和谷歌搜索了很多这样的问题,但是我还没有找到这样的东西。
Oluf Nielsen。
答案 0 :(得分:1)
在我看来,最好不要定义额外的表来处理这个因为很多性能问题。我喜欢处理这类事情是在products表中使用序列化列。使用这种方法可以减少直接在数据库中搜索的能力,但是无论如何你都不想这样做。要处理搜索,您必须添加某种索引搜索机制。像acts_as_ferret甚至是Solr或ElasticSearch。
如果您使用的是postgres,请查看https://github.com/softa/activerecord-postgres-hstore
对于Mysql,使用rails内置的“store” http://api.rubyonrails.org/classes/ActiveRecord/Store.html
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories
store :settings
end
要为每个类别设置标准,请执行以下操作:
class Category < ActiveRecord::Base
has_and_belongs_to_many :products
def criteria
@criteria_list ||= self[:criteria].split('|')
@criteria_list
end
def criteria=(names)
self[:criteria] = names.join('|')
end
end
每次将产品添加到类别时,请检查该类别中的所有条件是否在产品的属性哈希键中可用。如果不是,请根据需要添加默认值。
您还可以使用proc动态获取产品类别的所有条件字段中的访问者名称来为属性哈希存储设置访问者? (不确定这个,因为我之前没有这样做过)
您还可以使用products表中的类型字段来查看使用STI(单表继承)。 (这是有据可查的)这种方法稍好一些,因为当产品从一个类别移动到另一个类别时,属性不会改变。
class Gadget < Product
store_accessor :manufacturer, :model
end
class Phone < Gadget
store_accessor :os, :touch_screen, :is_smart
end
希望这有帮助
答案 1 :(得分:0)
否则,第二种方法将使用nosql数据库。尝试使用mongoid的mogodb,这是非常稳定的。这将很好地满足您对变量属性的要求。您也可以在以后轻松添加任何其他类别。
据我所知,使用mysql,你最终会创建多个dbs来存储这些动态数据,但这会妨碍性能。
更新 -
除了你的数据可以灵活使用nosql之外,在转移之前还需要考虑很多事情。我刚才建议你需要灵活的数据库结构。从mogodb docs开始,它们是一个很好的起点。