基本上,我们的想法是有很多不同的收藏品。单个集合中的所有项将具有相同的属性,但每个集合的属性列表将不同。每个项目的每个属性的值将存储在项目属性值。
中我正在尝试构建一个页面,用户可以在其中填充项目的属性。我假设嵌套表单是要走的路,但我不知道如何在控制器和页面上表示这一点,考虑到属性的名称在一个表中而值在另一个表中。 / p>
如果有人遇到或不得不处理类似的情况,我们将不胜感激。
由于
答案 0 :(得分:1)
这是一个潜在的解决方案。
class Collection
has_and_belongs_to_many :items
has_and_belongs_to_many :attributes
end
class Item
has_and_belongs_to_many :collections
has_many :item_attributes
has_many :attributes, though: :item_attributes
end
class Attributes
has_and_belongs_to_many :collections
has_many :item_attributes
has_many :items, though: :item_attributes
end
class ItemAttribute
belongs_to :item
belongs_to :attribute
end
让我们看一下数据库布局来支持这些模型:
ActiveRecord::Schema.define(version: 20151027173337) do
create_table "attributes_collections", id: false, force: :cascade do |t|
t.integer "attribute_id", null: false
t.integer "collection_id", null: false
end
create_table "collections", force: :cascade do |t|
t.string "title"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "collections", ["user_id"], name: "index_collections_on_user_id"
create_table "collections_items", id: false, force: :cascade do |t|
t.integer "collection_id", null: false
t.integer "item_id", null: false
end
create_table "item_attributes", force: :cascade do |t|
t.integer "item_id"
t.integer "attribute_id"
t.string "value"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "item_attributes", ["attribute_id"], name: "index_item_attributes_on_attribute_id"
add_index "item_attributes", ["item_id"], name: "index_item_attributes_on_item_id"
create_table "items", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
但当然,由于许多连接,性能将受到影响。此外,每个属性都将存储为VARCHAR,这意味着您无法在数据库中进行任何数字比较。
如果你真的需要灵活的架构,我会考虑使用HSTORE, JSON或其他动态列类型或无架构数据库,例如MongoDB。
首先,您应该非常熟悉使用accepts_nested_attributes_for
和fields_for
可以完成的工作,并且可以考虑使用AJAX将操作委托给CollectionController
和ItemController
后端,而不是把它全部塞进一个怪物。