动态CMS类似于轨道上的红宝石路线

时间:2009-04-22 08:55:35

标签: ruby-on-rails

我想创建一个像网站这样的CMS,用户可以从一些通用页面开始,即

  • 主页
  • 接触

从那里可以动态添加子页面,例如

  • 主页
    • 物品
      • 第一条
        • 东西
          • 东西-ELSE
      • 第二条
  • 接触

为实现这一目标,我计划使用某种自我指涉关联,例如

class Page < ActiveRecord::Base
  belongs_to :parent, :class_name => 'Page'
  has_many :children, :class_name => 'Page'
end

我正在努力的一件事是路线生成。因为页面可以动态添加,我需要为这些页面动态生成路由,并且无法知道页面可以嵌套多少层次

所以,如果我从主页开始: /

然后开始添加页面,例如

/用品/第一条/某事/东西,否则/另一-事情

如何通过rails路由模型实现类似的目标?

5 个答案:

答案 0 :(得分:9)

如果您有某种方法可以为Page条记录生成网址字符串(我会将该部分留给您),您只需映射config/routes.rb中的每一页:

Page.all.each do |page|
  map.connect page.url, :controller => 'pages', :action => 'show', :id => page
end

让观察者挂钩页面模型,以便在发生变化时重新加载路径:

class PageObserver < ActiveRecord::Observer
  def reload_routes(page)
    ActionController::Routing::Routes.reload!
  end
  alias_method :after_save,    :reload_routes
  alias_method :after_destroy, :reload_routes
end

不要忘记编辑config/environment.rb以加载观察者:

# Activate observers that should always be running
config.active_record.observers = :page_observer

答案 1 :(得分:8)

此问题的一个解决方案是从模型上的挂钩动态加载路径。例如,我网站上Slug模型的摘录:

class Slug < ActiveRecord::Base

  belongs_to :navigable

  validates_presence_of :name, :navigable_id
  validates_uniqueness_of :name

  after_save :update_route

  def add_route
    new_route = ActionController::Routing::Routes.builder.build(name, route_options)
    ActionController::Routing::Routes.routes.insert(0, new_route)
  end

  def remove_route
    ActionController::Routing::Routes.routes.reject! { |r| r.instance_variable_get(:@requirements)[:slug_id] == id }
  end

  def update_route
    remove_route
    add_route
  end

  def route_options
    @route_options ||= { :controller     => navigable.controller, 
                         :action         => navigable.action, 
                         :navigable_id   => navigable_id,
                         :slug_id        => id }
  end

end

在保存之后,以最高优先级(在内存中的路由数组中为0)插入路由。

此外,听起来你应该使用一个树管理插件,就像很棒的嵌套集或更好的嵌套集来管理你网站的树。

答案 2 :(得分:2)

您必须自己解析路线

map.connect '*url', :controller => 'pages', :action => 'show'

现在,您的操作中应该有一个params[:url]作为由斜杠分隔的数组的请求路径。一旦掌握了这些字符串,就可以从中找到所需的模型。

那是来自记忆,已经很久了。希望它适合你。

答案 3 :(得分:0)

看看RadiantCMS来源,就我理解他们的自我描述而言,他们实现了这个功能。

答案 4 :(得分:0)

我在Rails gem中实现了类似的功能,使用自引用关联和类似js接口的树来重新排序和嵌套“页面”。

模板语言和身份验证/授权留待开发人员实施。 https://github.com/maca/tiny_cms