所以,这可能更像是一个"软件工程"题。但我正在考虑如何在活动记录中存储Widget的详细信息。
假装小工具A有一个展示页面,在该展示页面中我们有一些手风琴式的样式" FAQS"或者那种效果。在手风琴中有一个列表,其中的子弹点突出显示了Widget A如何工作的不同内容,或者如何使用Widget A.
因为显然我们不想为每个小部件创建单独的页面,所以这些项目需要存储在某个地方。但我们也不想为数据库中的每一个创建10,20或30个单独的字段。那么解决方案是什么?
我的第一个想法是某种哈希或数组,但rails是否允许这样做?特别是如果它们是每个项目的长串。有没有更好的办法?
或者这样做的正确方法是将此声称为模型(如..." faq_item")或其他什么,然后为其需要的Widget提供参考ID? (这样" faq_item"模型/架构只需要几个字段,并且可以将引用ID分配给它所属的Widget。
答案 0 :(得分:1)
如果每个小部件只有少数" FAQ项目" (或"详细信息",因为我将引用它们),每个细节只不过是一个文本字符串,您可以将小部件的详细信息存储在序列化数组中: / p>
# models/widget.rb
class Widget < ApplicationRecord
# serialize the `details` attribute as JSON into
# the `details` column on the widgets table
serialize :details, JSON
end
# db/schema.rb
# ...
create_table "widgets", force: :cascade do |t|
t.string "name"
t.text "details"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
# rails console
wid = Widget.create!(
:name =>
'Wideband, Voltage-Feedback Operational Amplifier With Disable',
:details => [
'Flexible supply range: 5-V to 12-V Single Supply, +/- 2.5-V to 5-V Dual Supply',
'Unity-Gain Stable: 500 MHz (G = 1)',
'High Output Current: 190 mA',
'High Slew Rate: 1800 V/us',
'Wideband 5-V Operation: 220 MHz (G = 2)'
])
# => #<Widget ...>
wid.details.first
# => "Flexible supply range: 5-V to 12-V Single Supply, +/- 2.5-V to 5-V Dual Supply"
有关serialize
的更多信息,请查看Rails 5 serialization API。
但是,如果您需要为每个细节存储更多信息(例如,created_at / updated_at字段),或者每个窗口小部件都包含多个细节,那么为您创建窗口小部件详细信息的新表可能是谨慎的。提示:
# models/widget.rb
class Widget < ApplicationRecord
has_many :details, :dependent => :destroy
end
# models/widget/detail.rb
class Widget::Detail < ApplicationRecord
belongs_to :widget
end
# db/schema.rb
# ...
create_table "widget_details", force: :cascade do |t|
t.integer "widget_id"
t.text "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
wid = Widget.create!(
:name =>
'CMOS, 125 MHz Complete DDS Synthesizer',
:details => [
Widget::Detail.create!(:content => '125 MHz Clock Rate'),
Widget::Detail.create!(:content => 'On-Chip High Performance DAC'),
Widget::Detail.create!(:content => '32-Bit Frequency Tuning Word')
])
# => #<Widget ...>
wid.details.first
# => #<Widget::Detail ... content: "125 MHz Clock Rate" ...>
答案 1 :(得分:1)
如果您使用的是Postgres,则可以在数据库中使用JSONB类型字段。使用JSONB数据类型,您将能够获得非结构化数据,同时能够使用Postgres和ActiveRecord查询字段,而无需新表。
像这样:
rails g migration add_fields_to_widgets details:jsonb
rails db:migrate
在rails控制台中测试您的小部件创建。
Widget.create(name: "Widget Foo", details: { "how to use": "Instructions on how to use", "height": "12cm", "width": "100cm" })
如果您想要找到12厘米高的所有小部件,您只需要进行如下查询:
Widget.where("details->>'height' = ?", "12cm")
会返回你原来的Widget Foo对象,然后你就可以在你的前端使用纯JavaScript来操作它。