module ActiveScaffold::Actions::Nested

The Nested module basically handles automatically linking controllers together. It does this by creating column links with the right parameters, and by providing any supporting systems (like a /:controller/nested action for returning associated scaffolds).

Public Class Methods

included(base) click to toggle source
Calls superclass method
# File lib/active_scaffold/actions/nested.rb, line 6
def self.included(base)
  super
  base.module_eval do
    before_action :set_nested
    before_action :configure_nested
    include ActiveScaffold::Actions::Nested::ChildMethods if active_scaffold_config.columns.map(&:association).compact.any?(&:habtm?)
  end
  base.before_action :include_habtm_actions
  base.helper_method :nested
  base.helper_method :nested_parent_record
end

Protected Instance Methods

beginning_of_chain() click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 91
def beginning_of_chain
  # only if nested is related to current controller, e.g. not when adding record in subform inside subform
  if nested? && nested.match_model?(active_scaffold_config.model)
    nested_chain_with_association
  elsif nested? && nested.scope
    nested_parent_record.send(nested.scope)
  else
    active_scaffold_config.model
  end
end
configure_nested() click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 35
def configure_nested
  return unless nested?
  register_constraints_with_action_columns(nested.constrained_fields)
  return unless active_scaffold_config.actions.include? :list
  active_scaffold_config.list.user.label = nested_label
  return if active_scaffold_config.nested.ignore_order_from_association
  chain = beginning_of_chain
  active_scaffold_config.list.user.nested_default_sorting = nested_default_sorting(chain) if nested.sorted?(chain)
end
create_association_with_parent(record, check_match = false) click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 128
def create_association_with_parent(record, check_match = false)
  return unless create_association_with_parent?(check_match)
  if nested.child_association&.singular?
    record.send("#{nested.child_association.name}=", nested_parent_record)
  elsif nested.create_through_singular?
    through = nested_parent_record.send(nested.association.through_reflection.name) ||
              nested_parent_record.send("build_#{nested.association.through_reflection.name}")
    if nested.source_reflection.reverse_association.collection?
      record.send(nested.source_reflection.reverse) << through
    else
      record.send("#{nested.source_reflection.reverse}=", through)
    end
  else
    record.send(nested.child_association.name) << nested_parent_record
  end
end
create_association_with_parent?(check_match = false) click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 121
def create_association_with_parent?(check_match = false)
  # has_many is done by beginning_of_chain and rails if direct association, not in through associations
  return false unless nested.create_with_parent?
  return false if check_match && !nested.match_model?(active_scaffold_config.model)
  nested_parent_record.present?
end
include_habtm_actions() click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 61
def include_habtm_actions
  if nested&.habtm?
    # Production mode is ok with adding a link everytime the scaffold is nested - we are not ok with that.
    unless active_scaffold_config.action_links['new_existing']
      active_scaffold_config.action_links.add('new_existing', :label => :add_existing, :type => :collection, :security_method => :add_existing_authorized?)
    end
    add_shallow_links if active_scaffold_config.nested.shallow_delete
  elsif !ActiveScaffold.threadsafe
    # Production mode is caching this link into a non nested scaffold, when threadsafe is disabled
    active_scaffold_config.action_links.delete('new_existing')
    restore_shallow_links if active_scaffold_config.nested.shallow_delete
  end
end
nested() click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 20
def nested
  set_nested unless defined? @nested
  @nested
end
nested?() click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 25
def nested?
  !nested.nil?
end
nested_authorized?(record = nil) click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 57
def nested_authorized?(record = nil)
  true
end
nested_chain_with_association() click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 102
def nested_chain_with_association
  if nested.association.collection?
    nested_parent_record.send(nested.association.name)
  elsif nested.association.through? # has_one :through
    active_scaffold_config.model.where(active_scaffold_config.model.primary_key => nested_parent_record.send(nested.association.name)&.id)
  elsif nested.association.has_one?
    active_scaffold_config.model.where(nested.child_association.name => nested_parent_record)
  elsif nested.association.belongs_to?
    primary_key = active_scaffold_config.mongoid? ? '_id' : active_scaffold_config.model.primary_key
    active_scaffold_config.model.where(primary_key => nested_parent_record.send(nested.association.name))
  else # never should get here
    raise 'missing condition for nested beginning_of_chain'
  end
end
nested_default_sorting(chain) click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 53
def nested_default_sorting(chain)
  {:table_name => active_scaffold_config._table_name, :default_sorting => nested.default_sorting(chain)}
end
nested_label() click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 45
def nested_label
  if nested.belongs_to?
    as_(:nested_of_model, :nested_model => active_scaffold_config.model.model_name.human, :parent_model => ERB::Util.h(nested_parent_record.to_label))
  else
    as_(:nested_for_model, :nested_model => active_scaffold_config.list.label, :parent_model => ERB::Util.h(nested_parent_record.to_label))
  end
end
nested_parent_record(crud = :read) click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 117
def nested_parent_record(crud = :read)
  @nested_parent_record ||= find_if_allowed(nested.parent_id, crud, nested.parent_model)
end
set_nested() click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 29
def set_nested
  @nested = nil
  return unless params[:parent_scaffold] && (params[:association] || params[:named_scope])
  @nested = ActiveScaffold::DataStructures::NestedInfo.get(self.class.active_scaffold_config.model, params)
end

Private Instance Methods

nested_formats() click to toggle source
# File lib/active_scaffold/actions/nested.rb, line 147
def nested_formats
  (default_formats + active_scaffold_config.formats + active_scaffold_config.nested.formats).uniq
end