创建具有不同类型的内容块

时间:2014-12-18 16:53:04

标签: ruby-on-rails ruby ruby-on-rails-3

免责声明:我是一名PHP开发人员,对Rails有些新手。

我正在开发一个需要我创建内容块的应用程序。有不同类型的块,但它们共享共同的元素(标题,位置)。我难以缠绕大脑的问题是每个块可能以不同的方式定义其内容。

例如:

内容块(内容) - 此块存储用户输入的html,因此它将从数据库中提取其数据。

日历块(日历) - 此块显示事件列表,因此需要呈现视图

集成块(集成) - 此块是第三方集成块的示例。它可以通过解析json feed并以特定方式呈现它来获取其数据。

所以我的想法是将这些块类型中的每一个创建为注册块类型的模块或插件,并提供有关如何以及在何处获取该数据的信息。类似于Drupal的钩子系统的工作原理。我正在努力想出一个聪明的方法来构建这个。理论上可以有无限量的块类型,我想确保我可以保持这个代码库的模块化和组织。

非常感谢任何见解。

1 个答案:

答案 0 :(得分:0)

您可以使用策略模式:

假设您从数据库中获取了一些数据,例如:

block_content_from_db = [
  { block_type: "Content", content: "some html", ...any other attributes... },
  { block_type: "Calendar", content: "appointment data", ...any other attributes... },
  { block_type: "Integration", content: "integration data", ...any other attributes... }
]

并实现每个块类型和超类:

class Block
  def initialize(block_data)
    @block_data = block_data
    @renderer = Blocks.const_get "#{block_data[:block_type]}Block"
  end

  def render
    @renderer.new(@block_data).render
  end
end

module Blocks
  class ContentBlock < Block
    def initialize(block_data)
      @block_data = block_data
    end

    def render
      "Rendered ContentBlock: #{@block_data[:content]}"
    end
  end

  class CalendarBlock < Block
    def initialize(block_data)
      @block_data = block_data
    end

    def render
      "Rendered CalendarBlock: #{@block_data[:content]}"
    end
  end

  ... and so on ...
end

然后,渲染所有block_content_from_db

block_content_from_db.each do |block_data|
  Block.new(block_data).render
end

# => "Rendered ContentBlock: some html"
# => "Rendered CalendarBlock: appointment data"

现在,当您想要再次从Block添加一个新的块类型子类并定义一个render方法,该方法接受来自db的content以用于渲染。 content可以是阻止类型需要的任何内容。

您也不一定需要从Block继承子类,只要您想在子类之间共享公共方法。

通过将子类放在Blocks模块中,我们只是命名它们,以便稍后我们可以Blocks.constants获取所有已实现的块渲染器的列表,并在下拉菜单中使用它在UI中创建新block_content_from_db s。