【问题标题】:How do I design a model that should allow the user to create multiple fields?如何设计一个允许用户创建多个字段的模型?
【发布时间】:2016-01-23 22:45:47
【问题描述】:

我有一个Review 模型。我的用户应该能够撰写评论。 Review#New 的视图应该是管理员预先创建的带有文本字段的表单。

换句话说,我的admin-user 应该能够创建具有不同字段的 Review 模型的多个实例,甚至可能具有不同的输入类型(字符串、整数等)。这样,当普通用户登录时,他们会看到管理员用户为数据收集指定的不同表单字段。

当然,所有这些都应该存储在数据库中,以便在其存储的上下文中检索(也就是针对该特定模型)。

在 Rails 中解决此问题的最佳方法是什么?

把它想象成一个调查表和一个调查表构建器。

如果我可以使用 Simple-Form 来做到这一点会很好,但这不是必需的。

编辑 1

这是他们应该能够添加到评论中的字段类型的示例:

【问题讨论】:

标签: ruby-on-rails forms ruby-on-rails-4


【解决方案1】:

根据我的经验,数据库设计的很大一部分是通过简单地为事物找到正确的名称来帮助的。就您而言,我认为您在考虑调查或测验方面走在正确的轨道上。

查看survey gem 以获取想法。其中的基本模型是调查。调查有很多问题。问题有很多选项。调查也有许多尝试回答调查。然后尝试有很多答案。

因此,您的必然结果可能是拥有评论/评估(由管理员创建),其中可能有许多标准/查询(可能是不同类型,但我们会在一分钟内完成)。然后,您的用户将创建属于特定审核/评估并具有许多答案/响应的响应/评估。

对于不同的问题类型(简答、李克特量表评分、1-10、标签列表等),您可以在标准/查询上使用多态性。

希望我使用的这些名称中的一些对您有所帮助。随意使用同义词库以获得更多灵感。

编辑回复:多态性

免责声明:根据您的应用程序,多态性可能过于矫枉过正。

当然,我会扩展一些。不完全是。如果您还没有,请查看polymorphism 上的 rails 指南。我想你想要的是

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

【讨论】:

  • 嗯....这是个好主意。我真的很喜欢你的思维方式。您能否为我详细介绍一下不同的问题类型。因此,一个示例可能类似于critera_idcriteria_type,其中criteria_type 是与short_answer, likert, tag_list, etc. 等选项相关的枚举。是这个意思吗?
  • 抱歉,尝试将您的评论作为评论来回答,但编辑我的答案更容易。
  • 另外(尽管推荐这些变得越来越危险,因为它们已经过时了)还有一些不错的 Railscasts 可能会对您有所帮助。 196197196-revised。既然你提到你使用的是简单表单,你也可以看看cocoon
【解决方案2】:

从头开始解决。

根据我的经验,最简单的解决方案是使用hstorejsonjsonb 类型的字段。 这个解决方案与 Postgresql 数据库配合得很好。 要实现这种方法,您需要在 Review 模型中添加字段。

迁移:

# Reviews
def change
  add_column :reviews, :structure, :json
end

# Answers
def change
  add_column :answers, :values, :hstore
end

然后你可以定义模型ReviewStructureplain ruby​​ 类,这里你可以使用Virtus gem 轻松序列化它:

class ReviewStructure
  include Virtus.model
  attribute :fields, Array[Field]

  class Field
    include Virtus.model

    attribute :name
    attribute :type
  end
end

然后在 Review the serialization for structure 字段中定义:

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结构。

通过这种方法,您将能够创建具有不同类型字段的测验。

注意:

请记住,当前的实现将一条评论与一个答案联系起来,假设答案模型包含用户响应的所有值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    相关资源
    最近更新 更多