1

我们很快将在一个全新的 Rails 3 应用程序中重新编写一个使用了 5 年的 Rails 应用程序,该应用程序的代码基础非常不健全,并且具有所有新的热点。当前的应用程序有一个大量的自定义管理 UI 后端,它完全依赖于现在的管理框架。只是一些基本的控制器类和一些有用的 CSS 约定。但是维护这个 UI 需要做很多工作,特别是如果我们希望它看起来不错。

所以我在市场上寻找一个 Admin UI 框架,它可以让简单的东西变得微不足道,但没有在形式和功能上获得更复杂的定制方式。

顶级竞争者ActiveAdmin似乎很受欢迎,在玩了一会儿之后,我有些担心。它似乎声明了一个存在于单个 ruby​​ 文件中的完整唯一的 DSL。这有点简洁,但它也与大多数其他 Rails 应用程序的架构方式完全不同。它抽象了视图、控制器的助手,并为您提供了一个纯 ruby​​ DSL。在我看来,这会妨碍在我们的管理视图中做一些棘手的事情,更高级的自定义事情。DSL 很棒,除非您想做一些他们不明确支持的事情。

我的实验中的示例“资源”,没有控制器也没有视图。

ActiveAdmin.register Region do
  menu parent: "Wines"

  show title: :name

  index do
    column(:zone) { |o| link_to o.zone, admin_region_path(o) }
    column(:name) { |o| link_to o.name, admin_region_path(o) }
    default_actions
  end  
end

所以,问题:

  1. 是不是基于单独文件中的标准 Rails MVC 架构,以及管理区域的典型控制器继承实现,实际上我应该关注什么?从长远来看,它会阻碍可扩展性吗?
  2. ActiveAdmin 中的 DSL 是否比我认为的更好、更灵活?
  3. 我是否应该寻找其他一些更适合我的高度定制目标的框架?
  4. 我应该停止懒惰并自己动手吗?
  5. 选择Mongoid代替MySQL作为数据库是否会影响上述任何问题?
4

2 回答 2

2

值得一提的是,在 ActiveAdmin 中,您还可以使用 partials 创建自己的复杂表单

    form partial: 'my_form'

并使用控制器块扩展控制器功能。

   controller do
      def edit
      end

      def index
      end
   end
于 2012-11-16T00:32:39.043 回答
1

+1 活跃管理员,我在许多项目中使用它,包括我正在构建的 cms。它确实比许多新使用它的人认为它更灵活,在一天结束时你总是可以这样做:

controller do
  def custom_action
    Puts "hi"
  end
end

(认为​​这是从手机上写的正确语法,所以这一切都在脑海中)

另外,我对继承的资源发誓,这些资源是活动管理控制器扩展的,因为它们确实(以一种好的方式)迫使你编写宁静的、可重用的代码。底线是我相信活跃的管理员在我尝试过的其他人(railsadmin 和至少一个其他人)之前取得了飞跃式发展

更新:当然,这里是inherited_resources 文档

https://github.com/josevalim/inherited_resources

这是一个直接修改控制器的例子,来自我的小 CMS 项目。

ActiveAdmin.register Channel do

  index do
    column :title
    column :slug
    column "Fields" do |channel|
      "#{link_to('View Fields', admin_channel_entry_fields_path(channel))}    #{link_to 'Add Field', new_admin_channel_entry_field_path(channel)}".html_safe      
    end  
    column "Actions" do |channel|
      "#{link_to('View Entries', admin_channel_entries_path(channel))}    #{link_to 'Create Entry', new_admin_channel_entry_path(channel)}".html_safe
    end
    default_actions
  end

  form :html => { :enctype => "multipart/form-data" } do |f|
    f.inputs "Channel" do
      f.input :title
      f.input :display_name
      f.input :image
    end
    f.buttons
  end

  controller do

    def begin_of_association_chain
      current_site
    end

    def tags

      query = params[:q]
       if query[-1,1] == " "
         query = query.gsub(" ", "")
         ActsAsTaggableOn::Tag.find_or_create_by_name(query)
       end

       @tags = ActsAsTaggableOn::Tag.all
       @tags = @tags.select { |v| v.name =~ /#{query}/i }
       respond_to do |format|
         format.json { render :json => @tags.collect{|t| {:id => t.name, :name => t.name }}}
       end

    end

  end

end

基本上,我使用继承的资源 begin_of_association_chain 方法(我最喜欢的 IR 方法之一)将频道内的所有数据或从我的频道资源继承的任何管理资源限制到当前站点,而没有像 /admin/sites/1/channels 这样的 url - 因为我已经根据访问者输入的 url 设置 current_site。-- 无论如何,基本上一旦你在里面:

controller do
  puts self.inspect
end

返回实际的控制器本身,例如 Admin::ChannelsController(其中 < InheritedResources::Base,可能不是直接的,但此时所有 IH 控制器方法都应该可用)。

于 2012-11-16T08:33:59.807 回答