ActiveScaffold根据记录数据隐藏更新表单上的字段

时间:2011-04-26 19:13:45

标签: ruby-on-rails activescaffold

我有一个使用activescaffold的Rails应用程序,我想在某些记录的更新中隐藏一些字段。

我一直在尝试使用辅助方法,但我似乎无法让它工作。

这样做的最佳方式是什么?

4 个答案:

答案 0 :(得分:2)

执行此操作的最佳方法是使用activescaffold插件提供的安全方法模板之一(具体取决于您的需要)。

粘贴在activescaffold wiki:

  

模型方法:限制任何事物   其他

     

在模型对象上,您可以定义   方法(没有一个接受任何   参数)有四种格式中的任何一种,   根据您的需要   粒度

     

格式为:

* #{column_name}_authorized_for_#{crud_type}?

例如,如果您有一个名为user的基于activescaffold的控制器:

class Admin::UsersController < ApplicationController
  active_scaffold do |config|
    config.columns = [:username, :name, :email]
  end
end

您只想让用户能够更新用户名,如果他们是管理员,那么您可以这样做:

用户模型:

class User < ActiveRecord::Base

  # ActiveScaffold security template: #{column_name}_authorized_for_#{crud_type}?
  def username_authorized_for_update?
    # As soon as this method will return false 
    # the username field will not be available on the update form
    return true # Write logic to decide if username field should be visible
  end
end

Active Scaffold wiki链接:https://github.com/activescaffold/active_scaffold/wiki/Security

答案 1 :(得分:2)

如果您只想隐藏更新视图中的某些列,那么在控制器中配置它很容易。

您可以指定要查看的列:

class DocumentsController < ApplicationController
  active_scaffold :document do |config|
    config.columns = [ :id, :product, :title, :document_type, :author, :organization, :document_approver, :document_location ]
    config.list.columns = [ :id, :product, :title, :document_type, :author ]
    config.show.columns = [ :product, :title, :document_type, :author, :organization, :document_approver, :document_location ]
    config.create.columns = [ :product, :title, :document_type, :document_approver, :document_location ]
    config.update.columns = [ :product, :title, :document_type, :organization, :document_approver, :document_location ]
  end
end

或者您可以排除要隐藏的内容:

class DocumentsController < ApplicationController
  active_scaffold :document do |config|
    config.columns = [ :id, :product, :title, :document_type, :author, :organization, :document_approver, :document_location ]
    config.list.columns.exclude :organization, :document_approver, :document_location
    config.show.columns.exclude :id
    config.create.columns.exclude :id, :author, :organization
    config.update.columns.exclude :id, :author
  end
end

请注意,'config.columns'用于定义控制器的总列数,如果没有明确定义'list','show','create'或'update'中的任何一个,那么'默认情况下使用config.columns'。

这也意味着,如果您希望除“更新”之外的所有视图都显示相同的列,那么您可以将其定义为:

class DocumentsController < ApplicationController
  active_scaffold :document do |config|
    config.columns = [ :id, :product, :title, :document_type, :author, :organization, :document_approver, :document_location ]
    config.update.columns = [ :product, :title, :document_type, :organization, :document_approver, :document_location ]
  end
end

或者:

class DocumentsController < ApplicationController
  active_scaffold :document do |config|
    config.columns = [ :id, :product, :title, :document_type, :author, :organization, :document_approver, :document_location ]
    config.update.columns.exclude :id, :author
  end
end

答案 2 :(得分:0)

whizcreed的答案是正确的,事实上这些ActiveScaffold安全模型方法是按记录计算的,所以你可以在模型中做这样的事情:

def username_authorized_for_update?
  return true unless existing_record_check?
  return false if userrights != 'admin'
  return true
end

其中userrights是此记录中的字符串字段(不可否认的糟糕示例) - 但将此条件替换为您要检查现有模型对象的任何条件。

答案 3 :(得分:0)

其他答案中提到的安全模型方法是一个不错的选择,但是在我的情况下,我希望允许根据输入到其他列中的数据显示或隐藏该字段,通过 chaining form fields。使用安全模型方法时,不会为安全方法返回 false 的字段呈现任何内容,这会阻止 ActiveScaffold update_column javascript 在相关列更新时重新呈现该字段。

举个简单的例子,如果我的 WritingUtensilsController 有

config.columns[:type].form_ui = :select
config.columns[:type].options = { options: %w( pencil pen crayon ) }
config.columns[:type].update_columns = [ :ink_color ]
config.columns[:type].send_form_on_update_column = true

并且我希望ink_color字段仅在type下拉列表设置为“pen”时显示,使用安全方法在这里不起作用,因为当类型下拉列表更改时,我们无法找到ink_color列更新。

解决方案

覆盖ink_color 列(_ink_color_form_column.erb) 的表单列部分以有条件地呈现正常字段,或dl 标记内的隐藏输入(没有名称属性但具有正确的类),具体取决于是否或不是书写工具是钢笔:

writing_utensils/_ink_color_form_column.erb:

<% if record.is_pen? %>
  <%= form_attribute(column, record, scope, false) %>
<% else %>
  <dl><input type="hidden" class="<%= column.name %>-input"></dl>
<% end %>

调用 form_attribute 方法将导致列正常呈现。但是,当记录不是钢笔时,隐藏输入将允许 javascript 将输入的父级 dl 定位为类 ink_color-input,以便在用户更新类型列时进行替换。

奖励:

在您的控制器中添加一个 after_render_field 方法以在 update_column 过程发生时操作您的记录:

def after_render_field(record, column)
  if column.name == :type
    if record.type == 'pen'
      record.last_sharpened = nil
    end
  end
end

如果您还希望使用新值重新渲染它,请务必将 last_sharpened 添加到 update_columns 数组中