常见问题

我正在使用活动脚手架,但是它看上去就像普通的脚手架一样丑陋。为什么?

首先检查有没有在你的布局中包含样式表。请参考 教程引言中的步骤,看看如何包含样式表。你还需要检查一下页面资源,确保有<style>标记。

如果这些都有了,请检查控制器相对应的视图目录。比如,如果你正在用PostsController,就检查app/views/posts。删除(或者移动)这个目录里所有的视图文件。可能在你运行Rails自带的脚手架生成器时,生成了这些视图和局部视图文件,它们会覆盖活动脚手架的视图。

还不行?可以去论坛提问,记得说一声你已经查过这个常见问题列表了。

500内部错误?光提示这个一点都没用!

没错,你说得对,但是不完全对。这条报错信息不完全是为了开发人员看的,主要是为最终用户有一个大概提示,有点儿像Gmail的错误信息。作为开发人员,看到返回500你就可以知道代码里发生了异常。马上检查logs/development.log的最后几行,你会看到真正的错误提示。

我的关联模型显示成 #<User:0xb7c88a2c>。我能修改它吗?

你可以在模型中定义一个to_label方法

class User < ActiveRecord::Base
  def to_label
    "User: #{username}"
  end
end

那些子表单很妙,但是有时候我想关掉这个功能。怎样可以简化表单中的关联?

这个form_ui = :select选项可以把表单界面中标准的子表单配置切换成简单的选择配置。这个配置可以为每个字段设置。

class UsersController < ApplicationController
  active_scaffold :users do |config|
    # 用户不能再在User表单中创建/编辑Roles了
    config.columns[:roles].ui_type = :select
  end
end

怎样在表单中加入自动补全?

使用表单覆盖插入所有必要的javascript。下面是Google群组里的一位朋友提供的例子,使用一个局部视图:

<div style="{height: 100px;}">
  <label for="@record[:identity_type]">Identity Type</label>
  <%= text_field_tag 'record[identity_type]', @record[:identity_type]%>
  <div class="auto_complete" id="identity_type_autocomplete_<%=@record[:id]%>" style="{height: 80px;}"></div>

  <%= javascript_tag("new Autocompleter.Local('record[identity_type]',
    'identity_type_autocomplete_#{@record[:id]}',
    ['User', 'Group', 'AdminUser'],
    {fullSearch: true, frequency: 0, minChars: 1});") -%>
  </div>

活动脚手架报了一个“不合式的约束(Malformed Constraint)”。我应该检查什么?

也许你已经注意到了,当你打开一个嵌套式脚手架时,首先它会检查这个关联是否双向的。举例来说,如果一个UserGroup has_many Users,那么请确保一个User必须同时belongs_to UserGroup。如果这样还不能修正这个问题,请再检查一下你的关联──是否具备一个清晰的“回路”关联?比如,考虑下列配置:

class Project < ActiveRecord::Base
  has_many :projects_users
  has_many :administrators, :through => :projects_users, :source =>:user,
    :conditions => "projects_users.role_type = 3"
  has_many :managers, :through => :projects_users, :source => :user,
    :conditions => "projects_users.role_type = 2"
  has_many :workers, :through => :projects_users, :source => :user,
    :conditions => "projects_users.role_type = 1"
end

class User < ActiveRecord::Base
  belongs_to :organization
  has_many :projects_users
  has_many :projects, :through => :projects_users, :source => :project
end

当活动脚手架试图显示某位User的嵌套Projects的时候,这个配置会出错。要想嵌套正确,活动脚手架需要知道回路关联。本例中Project并不具备一个清晰的指向User模块的连接(它有三个特别的关联)。所以,你必须加上:

class Project < ActiveRecord::Base
  has_many :users, :through => :projects_users, :source => :user
  ...
end

我的一个数据表有很多关联,然后我的数据库堵死了。为什么?怎么办?

当显示列表的时候,活动脚手架会使用预载入(eager loading)机制。这是基于一个假设,假设关联的每个字段都可能需要显示在这个列表上。如果字段太多了,你有两个选择:

  1. 从列表中移除一些关联字段(比如:config.list.columns.exclude :association_column
  2. 禁止某些关联字段的预载入机制,设置:config.columns[:association_column].includes = nil

我在params[:record]里面加了些东西,但是活动脚手架没有用到它。为什么?

活动脚手架不会用到整个params[:record]散列表,而只接受在白名单里的字段。这就是说,如果活动脚手架知道role_id不在表单里,它就会忽略params[:record][:role_id]条目。如果它不这么做,就会存在安全隐患,黑客们甚至可以利用它随心所欲。

如果你希望在保存记录前加入一些额外的数据,你可以在控制器中定义before_create_save(record)或者 before_update_save(record)。活动脚手架会检查这些方法,并将record对象传给它们。这样你就可以做比方说:指定当前用户为这条记录的主人。

我需要定制CSS(或者JavaScript)。最好的方法是什么?

请不要在public/目录中编辑活动脚手架文件!每次服务器启动的时候这些文件都会自动从vendor/plugins/active_scaffold目录中复制过来,以确保你使用的是最新的代码。所以,用对待其他活动脚手架代码的方式来对待它们──在其他地方覆盖它们,或者用Piston并编辑vendor/plugins/active_scaffold目录中的原始文件。

比如,如果你想定制CSS,创建public/stylesheets/active_scaffold_overrides.css文件,并在你的布局文件中包含它:在<%= active_scaffold_includes >之后放上<%= stylesheet_link_tag 'active_scaffold_overrides' >