Skip to content

Per Request Configuration

Sergio Cambra edited this page Jul 3, 2024 · 5 revisions

This is an advanced and experimental technique. It may have unknown quirks.

Sometimes you need to configure your scaffold differently for each request. At some level you can do this with the security layer, e.g. authorizing/forbidding the update action. But if you need to fiddle with things not covered by the security layer, you can use a before_filter to modify the configuration per-request. The basic setup is like this:

before_action :update_table_config

def update_table_config         
  if current_user
    # Change things one way
  else
    # Change things back the other way
  end 
end

Probably the most obvious change is to add or remove columns from the table or to change the column’s (or table’s) labels (giving for example Scott’s Tags or Richard’s Tags instead of just Tags). In order to add or remove columns the way to go is to define all the required columns in the initial configuration and then exclude those that are unwanted in the before_filter. Labels can be updated by a simple assignment.

Don’t forget to change the configuration back to the way it was if not using threadsafe! In the production environment the configuration is cached in class variables, and changing it for one special user will change it for all users … unless you change it back.

def update_table_config
  if current_user 
    active_scaffold_config.list.columns.exclude :not_required
    active_scaffold_config.label = current_user.name
    active_scaffold_config.columns[:tags].label = current_user.name+"'s Tags"
  else
    active_scaffold_config.list.columns.add :not_required
    active_scaffold_config.label = 'Users'
    active_scaffold_config.columns[:tags].label = 'Tags'
  end
end

Changes to columns are better handled with helpers. For example for the label, there are different helpers, so it supports different labels in list, show, form and subform:

In the list, with column_heading_label:

def column_heading_label(column)
  if column == :tags && current_user
    "#{current_user.name}'s Tags"
  else
    super
  end
end

In the form, with form_column_label:

def form_column_label(column, record, scope)
  if column == :tags && current_user
    record.tags.present? ? "#{current_user.name}'s Tags" : "Add tags for #{current_user.name}"
  else
    super
  end
end

In the subform, with horizontal layout (table), no record available, with subform_label:

def subform_label(column, hidden)
  if column == :tags && current_user
    "#{current_user.name}'s Tags"
  else
    super
  end
end

In the show, with show_label:

def show_label(column)
  if column == :tags && current_user
    "#{current_user.name}'s Tags"
  else
    super
  end
end

To change column’s options for the form_ui, a form override can be used to call the form_ui helper method (active_scaffold_input_<form_ui>), with different options based on conditions, passed as named argument ui_options. For example, to use different options on create or update form, use @record.new_record? for create when is true, and update when is false, or condition based on the value of some column:

def parent_user_form_column(record, options)
  column = active_scaffold_config.columns[:user]
  is_admin = current_user.admin? #example dynamic condition
  ui_options = {params: {admin_param: is_admin}}
  active_scaffold_input_record_select(column, options, ui_options: ui_options)
end
Clone this wiki locally