我有一个使用 activescaffold 的 Rails 应用程序,我想在某些记录的更新中隐藏一些字段。
我一直在尝试使用辅助方法来做到这一点,但我似乎无法让它发挥作用。
做这个的最好方式是什么?
我有一个使用 activescaffold 的 Rails 应用程序,我想在某些记录的更新中隐藏一些字段。
我一直在尝试使用辅助方法来做到这一点,但我似乎无法让它发挥作用。
做这个的最好方式是什么?
如果您只想在更新视图中隐藏某些列,那么在控制器中进行配置非常容易。
您可以指定要查看的列:
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
最好的方法是使用 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
活动脚手架 wiki 链接:https ://github.com/activescaffold/active_scaffold/wiki/Security
whizcreed 的回答是正确的,这些 ActiveScaffold 安全模型方法实际上是按记录评估的,因此您可以在模型中执行以下操作:
def username_authorized_for_update?
return true unless existing_record_check?
return false if userrights != 'admin'
return true
end
其中 userrights 是此记录上的一个字符串字段(诚然糟糕的示例) - 但将此条件替换为您要在该现有模型对象上检查的任何内容。
其他答案中提到的安全模型方法是一个不错的选择,但是在我的情况下,我希望通过链接表单字段来允许根据输入到其他列中的数据来显示或隐藏该字段。使用安全模型方法时,不会为安全方法返回 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字段仅在类型下拉列表设置为“笔”时显示,使用安全方法在这里不起作用,因为当类型下拉列表更改时,我们无法找到要更新的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
当 update_column 过程发生时,在控制器中添加一个after_render_field
方法来操作您的记录:
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 数组