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

KJF*_*KJF 7 ruby-on-rails

我想创建一个类似CMS的站点,用户可以从一些通用页面开始,即

  • 主页
  • 关于
  • 联系
  • 等等

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

  • 主页
    • 用品
      • 第1条
        • 某物
          • 东西,别的
      • 第二条
  • 关于
  • 联系
  • 等等

为了达到这个目的,我计划使用某种自我指涉关联

class Page < ActiveRecord::Base
  belongs_to :parent, :class_name => 'Page'
  has_many :children, :class_name => 'Page'
end
Run Code Online (Sandbox Code Playgroud)

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

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

然后开始添加页面即

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

如何使用rails路由模型实现类似的功能?

kch*_*kch 9

一旦你有办法为你的Page记录生成URL字符串(我将把那部分留给你),你可以只映射每一页config/routes.rb:

Page.all.each do |page|
  map.connect page.url, :controller => 'pages', :action => 'show', :id => page
end
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

# Activate observers that should always be running
config.active_record.observers = :page_observer
Run Code Online (Sandbox Code Playgroud)


Ben*_*use 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
Run Code Online (Sandbox Code Playgroud)

这将在保存后以最高优先级(在内存中的路由数组中为0)插入路由.

此外,听起来您应该使用树管理插件,并使用令人敬畏的嵌套集或更好的嵌套集来管理您网站的树.


Ale*_*yne 2

你必须自己解析路线

map.connect '*url', :controller => 'pages', :action => 'show'
Run Code Online (Sandbox Code Playgroud)

现在,您的操作中应该有一个params[:url]可用的请求路径,作为由斜杠分隔的数组。一旦你有了这些字符串,从那里找到你需要的模型就很简单了。

这是凭记忆写的,已经过去很久了。希望对你有帮助。