我有一个使用activescaffold的Rails应用程序,我想在某些记录的更新中隐藏一些字段。
我一直在尝试使用辅助方法,但我似乎无法让它工作。
这样做的最佳方式是什么?
答案 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
标记内的隐藏输入(没有名称属性但具有正确的类),具体取决于是否或不是书写工具是钢笔:
<% 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 数组中