ActiveScaffold在基于记录数据的更新表单上隐藏字段



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

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

最好的方法是什么?

最好的方法是使用activescaffold插件提供的安全方法模板之一(取决于您的需要)。

粘贴自activescaffold wiki:

模型方法:限制任何东西其他

在你的模型对象上你可以定义方法(它们都不接受任何参数)四种格式中的任何一种,取决于你的需要粒度。

格式为:

* #{column_name}_authorized_for_#{crud_type}?

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

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

如果你想让用户更新用户名如果他们是admin你可以这样做:

用户模式:

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

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

您可以指定要查看的列:

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. conf。Columns '用于定义控制器的列总数,如果'list', 'show', 'create'或'update'中的任何一个都没有明确定义,则'config '。Columns '默认使用

这也意味着,如果你想让相同的列在所有视图中可见,除了'update',那么你可以这样定义:

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

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字段只在类型下拉框被设置为"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以类ink_color-input为目标来替换输入的父dl,当类型列被用户更新时。

奖金:

在控制器中添加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

如果您希望使用新值重新呈现,请确保将lastrongharpened添加到update_columns数组

相关内容

  • 没有找到相关文章

最新更新