我有一个Review
模型。我的用户应该能够撰写评论。 Review#New
的视图应该是管理员事先创建的带有文本字段的表单。
换句话说,我的admin-user
应该能够创建具有不同字段的Review模型的多个实例,甚至可能是不同的输入类型(字符串,整数等)。这样,当普通用户登录时,他们会看到管理员用户为数据收集指定的不同表单字段。
当然,所有这些都应存储在数据库中,以便在存储的上下文中进行检索(也就是特定模型)。
在Rails中处理此问题的最佳方式是什么?
将其视为调查表和调查表构建者。
如果我能用简单形式做到这一点会很好,但这并不是一个要求。
修改1
以下是他们应该能够添加到评论中的字段类型的示例:
答案 0 :(得分:3)
根据我的经验,通过简单地找到正确的名称来帮助数据库设计的很大一部分。在你的情况下,我认为你正在考虑调查或测验的正确轨道。
查看survey gem的想法。其中基础模型是Surveys。调查有很多问题。问题有很多选项。调查也有许多尝试,回答调查。尝试然后有很多答案。
因此,您的必然结果可能是评论/评估(由管理员创建)可能有许多标准/查询(可能有不同类型,但我们会在一分钟内完成)。然后,您的用户将创建属于特定评论/评估的响应/评估,并有许多答案/回复。
对于不同的问题类型(简答,李克特评分,1-10,标签列表等),您可以在条件/查询中使用多态。
希望我用过的其中一些名字会对你有所帮助。随意使用词库获得更多灵感。
EDIT Re:Polymorphism
免责声明:根据您的应用程序,多态性可能过度。
当然,我会扩展一些。不完全是。如果您还没有,请查看polymorphism上的导轨指南。我想你想要的是
class Criterion < ActiveRecord::Base
belongs_to :askable, polymorphic: true
end
然后我会为每个问题/标准类型制作一个模型。例如:
class ShortAnswer < ActiveRecord::Base
has_many :criteria, as: :askable
end
class Likert < ActiveRecord::Base
has_many :criteria, as: :askable
end
旁注:如果rails没有正确地将条件多元化为条件,则可能需要将以下内容添加到config / initializers / inflections.rb文件中
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'criterion', 'criteria'
end
答案 1 :(得分:2)
Scratch solution。
根据我的经验,最简单的解决方案是使用hstore,json或jsonb类型的字段。
这个解决方案适用于Postgresql数据库。
要实现此方法,您需要在Review
模型中添加字段。
# Reviews
def change
add_column :reviews, :structure, :json
end
# Answers
def change
add_column :answers, :values, :hstore
end
然后你可以定义模型ReviewStructure
普通红宝石类,在这里你可以使用Virtus gem来轻松地序列化它:
class ReviewStructure
include Virtus.model
attribute :fields, Array[Field]
class Field
include Virtus.model
attribute :name
attribute :type
end
end
然后在Review中定义结构字段的序列化:
class Review < ActiveRecord::Base
...
serialize :structure, ReviewStructure
end
然后,您可以使用review.structure.fields
访问评论的结构字段。
<% simple_form_for @answer do |f| %>
<% @review.structure.fields.each do |field| %>
<% f.input "values[#{field.name}]", as: field.type %>
<% end %>
<% end %>
answer.values.each do |field_name, value|
...
end
至于管理员,最好在客户端(使用js)处理审核结构的创建,并通过API发布纯JSON结构。
通过这种方法,您将能够创建具有不同类型字段的测验。
请记住,当前实施将一个评论连接到一个答案,假设答案模型包含用户响应的所有值。