Apr 30 2008

ActiveScaffoldExt之四:高级搜索

Tag: activescaffold, enterprise, plugincaoweiyuan @ 6:02 pm

简介

按字段搜索是ActiveScaffold的一个隐藏功能。虽然文档没有涉及(我们会在下面具体介绍用法),但是相信细心的用户已经发现了。ActiveScaffold缺省的搜索很有web应用程序风格,但是企业应用的话,按字段搜索更加普遍。它甚至还可以用来生成报表,对不对?这是我们当时选择ActiveScaffold的原因之一。

然而ActiveScaffold的按字段搜索做的不太地道,所有的字段都是文本输入框,而我希望看到像创建编辑界面那样丰富的表单项。通过这个扩展,你就可以做到:

  • 对于定义了form_ui=:select的字段,搜索表单项也是个下拉列表框。
  • 数字字段有了运算符,除了缺省的等于,还有>, >=, <, <=, !=,甚至还可以按范围搜索
  • 除了众望所归的日期范围(自定义),还有一些预设的区间,比如:今年,本季度,上个月等等。另外,为了配合报表图表功能,还有一个“趋势”区间,可以设定为“最近5周以来”这样的范围。

安装

请参考批量创建的安装。

用法

激活ActiveScaffold中的field_search功能:

config.actions.swap :search, :field_search

然后定义需要搜索的字段:

config.field_search.columns = :brand, :size, :created_at

假设你已经定义了某个belongs_to字段的form_ui为:select:

config.columns[:brand].form_ui = :select

并且日期字段的form_ui也必须是:calendar_date_select(需要安装calendar_date_select插件):

config.columns[:created_at].form_ui = :calendar_date_select

这样就搞定了。

Demo

还是用上次批量创建运动鞋的模型,为了演示日期范围搜索,我们加上了created_at字段。点那个搜索按钮,你就能看到惊艳的高级搜索界面了。

如果你已经svn update了最新的l10n_scaffold插件,会发现这个新功能的汉化也在其中了。


Apr 24 2008

ActiveScaffoldExt之三:过滤列表

Tag: activescaffold, enterprise, plugincaoweiyuan @ 5:43 pm

简介

在企业应用中常常有这样的要求,比如,同样一个业务列表,核价员要看到待审核状态和重新提交状态的,生产调度员要看到生产状态和采购状态的…业务员要看到所有状态的。他们都需要对业务列表进行过滤。过滤有时候是基于一个字段,比如业务状态,也可能会基于两个字段,比如业务状态和核准与否。这就是这个扩展要解决的问题。

市面上还有一个叫做activescaffoldlistfilters的插件可以参考,这是一个更通用的插件,把belongs_to关联中的所有可能性列出,给用户复选。

安装

请参考批量创建的安装。

用法

你可以为一个状态指定一个过滤选项,像这样:

config.list.add_filter "preparing", :status => "preparing"

你还可以把几个状态值放在一个过滤选项里,就像这样:

config.list.add_filter "processing", :status => ["placed", "processing"]

一个过滤选项的条件也可以是几个字段,就像这样:

config.list.add_filter "finished", :status => "processed", :verified => true

label选项给你用来指定显示的文本,如果不指定的话,它就会用这个过滤选项的name来做文本,一般中文项目都是需要指定一下的,就像这样:

config.list.add_filter "preparing", :label => "刚下单", :status => "preparing"

如果你需要给这些选项加上条件,比如哪些人可以看到什么,可以给list动作加一个before_filter,就像这样:

class OrdersController < ApplicationController
  before_filter :add_filter_options, :only => :index
  def add_filter_options
    active_scaffold_config.list.add_filter “preparing”, :status => “preparing”
    active_scaffold_config.list.add_filter “processing”, :status => [”placed”, “processing”]
    if current_user.has_role?(’moderator’)
      active_scaffold_config.list.add_filter “finished”, :status => “processed”, :verified => true
    end
  end
end

注:这往往需要和security功能配合使用。

这里面还有一个彩蛋功能──可以让浏览器记住你上次过滤的选项,自己来找找看吧。

Demo

这里是一个Demo,如果你已经svn update了最新的l10n_scaffold插件,会发现这个新功能的汉化也在其中了。


Apr 10 2008

ActiveScaffoldExt之二:多选列表和批量删除

Tag: activescaffold, enterprise, plugincaoweiyuan @ 12:21 pm

ActiveScaffoldExt之一我们介绍的是批量创建(batch_create)。那么当然也需要有一个批量删除。批量删除的首要条件是可以在列表里多选,这是在ActiveScaffold论坛中很多人希望有的功能。于是,我们的第二个扩展就来实现多选列表和批量删除。

简介

在列表中选中多个记录,批量执行一个动作(我们管它叫macro),这就是多选列表的功能。我们已经为批量删除定义好了一个macro,叫做“batch_destroy”,你可以直接用。如果你需要其他特殊功能,则需要在你的controller,或者ApplicationController里定义一个动作。

安装

请参考批量创建的安装。 

用法

controllers/sneakers_controller.rb

active_scaffold do |config|
  # 添加macro: 批量删除
  config.add_macro 'batch_destroy', :label => 'Delete', :method => :delete, :security_method => :delete_authorized?
end

config.add_macro的参数与config.action_links.add的参数(参考文档:api-action-link)类似,但是如果你设置了:type参数,则会被我们的缺省值:table覆盖,因为对于需要批量执行的macro命令,当然应该出现在列表的表头,而不是每个记录的右边。另外需要注意的是,批量删除的macro名称是batch_destroy,而不是batch_delete

Demo

这里是一个Demo,使用的是与批量创建相同的运动鞋的例子。如果你已经svn update了最新的l10n_scaffold插件,会发现这个新功能的汉化也在其中了。


Apr 02 2008

ActiveScaffoldExt之一:batch_create

Tag: activescaffold, enterprise, plugincaoweiyuan @ 5:21 pm

批量创建(batch_create)是我们从项目中抽象出来的第一个ActiveScaffoldExt,用以在一个表单中批量创建很多记录。

简介

假设我们有一个ActiveRecord的模型叫做Sneaker(运动鞋),有这么几个属性:品牌、尺寸、颜色,当然还有名称。品牌可能是Adidas、Nike或者别的,尺寸假设是7、8和9(英寸),颜色包括红蓝白。如果我们需要把这个排列组合里的每个情况都加入sneakers表,而又不想输入2×3x3次创建表单,那么你就需要用到这个批量创建功能。在我们编程提出DRY的口号的同时,我们软件的客户也同样希望不要做重复的机械性操作。在我们的项目中,有多个模型需要用到批量创建,比如物料列表,货架编号等等。有关实现这个功能的核心算法,我们已经在javaeye的一篇帖子中讨论过了。

安装

将activescaffold-ext安装到你项目的插件中,安装插件有很多方法,我们建议用svn propedit svn:externals vendor/plugins的方法,这样可以通过svn update保持与我们的开发同步,svn repository的地址是:http://activescaffold-ext.googlecode.com/svn/trunk/。然后,你还需要将frontends/ext/目录中的所有文件copy(或者merge)到你的app/views/active_scaffold_overrides目录中。这一步需要手工来做,你也许会觉得不太方便,那是因为如果你已经在active_scaffold_overrides里面做了一些模板覆盖的话,直接强行copy会搞乱你本来的开发,所以你需要手工做一个merge。

用法

models/sneaker.rb

belongs_to :brand

def to_s
  "#{size}in #{brand} in #{color}"
end

controllers/sneakers_controller.rb

active_scaffold do |config|
  # 以active_scaffold的语法定义create的columns
  config.create.columns = :name, :brand, :size, :color

  # 添加动作batch_create
  config.actions.add :batch_create

  # batch_create的字段会从create.columns自动继承
  # 然后将那些需要批量输入的字段定义到batch_columns
  config.batch_create.batch_columns = :brand, :size, :color

  # 在batch_create里无需关注的字段(通常会在创建后自动生成,请看before_create_save)
  config.batch_create.ignore_columns = :name

  # 将关联字段的form_ui定义为select
  columns[:brand].form_ui  = :select
end

def before_create_save(name)
  return if record.name

  # 如果是从batch_create来的,则自动生成名称
  record.name = record.to_s
end

batch_create也支持活动脚手架的表单覆盖,命名规则是:字段名_batch_form_column。比如,对于品牌选择框,我们希望如果一种品牌已经超过20种运动鞋,就将它隐去,那么我们可以在helpers/sneakers_helper.rb中定义一个brand_batch_form_column方法:

def brand_batch_form_column(record, input_name)
  select_tag input_name + '[id][]', options_from_collection_for_select(
    Brand.find(:all).select{|brand| brand.sneakers.count < 20},
    "id", "name"), :multiple => true
end

Demo

这里是一个Demo,使用的就是上面运动鞋的例子。例子并没做汉化,相信大家都能看懂。如果你已经svn update了最新的l10n_scaffold插件,你会发现batch_create的汉化也在其中了。


Mar 28 2008

着手构建活动脚手架扩展

Tag: activescaffold, enterprise, plugincaoweiyuan @ 3:23 pm

产品基本上线了以后,开始有空将我们做的扩展开发剥离出来,共享成一个独立的插件。

这是一个功能列表:

  1. 批量创建 BatchCreate
  2. 扩展field_search,加入日期范围和数字运算符
  3. 可多选的列表
  4. 列表过滤器
  5. 发邮件
  6. 打印
  7. 专为AS配置的acts_as_trackable,记录所有修改
  8. fushion图表支持

由于这些功能大部分都会涉及模板覆盖(并且某些功能会修改同一个模板文件),所以我们会把他们做在一个插件中。但这并不意味着用户必须全盘接受这些功能,它们都可以通过在active_scaffold中配置来添加和删除这些功能。

这是项目主页:activescaffold-ext