Class: ElaineCrud::BaseController

Inherits:
ActionController::Base
  • Object
show all
Includes:
ActionView::Helpers::DateHelper, ActionView::Helpers::NumberHelper, ActionView::Helpers::TagHelper, ActionView::Helpers::TextHelper, ActionView::Helpers::UrlHelper, DSLMethods, ExportHandling, FieldConfigurationMethods, LayoutCalculation, ParameterHandling, RecordFetching, RelationshipHandling, SearchAndFiltering, SortingConcern
Defined in:
app/controllers/elaine_crud/base_controller.rb

Overview

Base controller providing CRUD functionality for ActiveRecord models

Usage:

class PeopleController < ElaineCrud::BaseController
model Person
permit_params :name, :email, :phone
end

Instance Method Summary collapse

Methods included from ExportHandling

#export

Methods included from RelationshipHandling

#apply_has_many_filtering, #detect_parent_filters, #find_reflection_by_foreign_key, #get_all_relationship_includes, #get_belongs_to_includes, #get_habtm_includes, #get_has_many_includes, #get_has_one_includes, #populate_parent_relationships, #redirect_after_create_path, #set_parent_context, #valid_parent_filter?

Methods included from LayoutCalculation

#calculate_layout, #calculate_layout_header

Methods included from FieldConfigurationMethods

#apply_field_defaults, #configured_fields, #debug_configuration, #determine_display_field_for_model, #field_config_for, #field_configured?, #field_description, #field_readonly?, #field_title, #readonly_field_display, #render_field_display, #render_field_edit, #turbo_disabled?

Methods included from SearchAndFiltering

#apply_date_range_filters, #apply_field_filter, #apply_filters, #apply_global_search, #apply_search_and_filters, #determine_date_columns, #determine_filterable_columns, #determine_searchable_columns, #filters, #get_column_type, #infer_filter_type, #search_active?, #search_query, #total_unfiltered_count, #valid_filter_field?

Methods included from SortingConcern

#current_sort_column, #current_sort_direction, #toggle_sort_direction

Instance Method Details

#cancel_editObject



192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'app/controllers/elaine_crud/base_controller.rb', line 192

def cancel_edit
  @record = find_record
  @model_name = crud_model.name
  @columns = determine_columns

  # For Turbo Frame requests, return just the view row partial
  if turbo_frame_request?
    header_layout = calculate_layout_header(@columns.map(&:to_sym))
    render partial: 'elaine_crud/base/view_row', locals: { record: @record, columns: @columns, header_layout: header_layout }
  else
    # For direct access, redirect to index
    redirect_to action: :index
  end
end

#createObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'app/controllers/elaine_crud/base_controller.rb', line 83

def create
  @record = crud_model.new(record_params)

  # Ensure parent relationship is maintained
  populate_parent_relationships(@record) if @record.errors.any?

  if @record.save
    # Handle modal mode (nested create)
    if params[:modal_mode] == 'true' && params[:return_field].present?
      # Get field configuration from the parent controller
      parent_controller_class = "#{params[:parent_model].pluralize.camelize}Controller".constantize
      parent_controller = parent_controller_class.new
      parent_field_config = parent_controller.send(:field_config_for, params[:return_field].to_sym)

      render turbo_stream: turbo_stream.replace(
        "#{params[:return_field]}_select_wrapper",
        partial: 'elaine_crud/base/foreign_key_select_refresh',
        locals: {
          field_name: params[:return_field],
          selected_id: @record.id,
          field_config: parent_field_config,
          parent_model: params[:parent_model]
        }
      )
    else
      # Redirect back to filtered view if came from parent context
      redirect_to redirect_after_create_path, notice: "#{crud_model.name} was successfully created.", status: :see_other
    end
  else
    @model_name = crud_model.name
    @modal_mode = params[:modal_mode] == 'true'

    if @modal_mode
      render 'elaine_crud/base/new_modal', layout: false, status: :unprocessable_entity
    else
      render 'elaine_crud/base/new', status: :unprocessable_entity
    end
  end
end

#destroyObject



207
208
209
210
211
# File 'app/controllers/elaine_crud/base_controller.rb', line 207

def destroy
  @record = find_record
  @record.destroy
  redirect_to polymorphic_path(crud_model), notice: "#{crud_model.name} was successfully deleted.", status: :see_other
end

#editObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/controllers/elaine_crud/base_controller.rb', line 123

def edit
  @record = find_record
  @records = fetch_records  # Fetch all records for the edit page
  @model_name = crud_model.name
  @columns = determine_columns

  # Set search/filter metadata for the edit page (which includes search bar)
  @search_query = search_query
  @active_filters = filters
  @searchable_columns = determine_searchable_columns
  @filterable_columns = determine_filterable_columns
  @total_count = total_unfiltered_count if search_active?

  # If Turbo is disabled, render standalone edit form (no table context)
  if turbo_disabled?
    render 'elaine_crud/base/edit_standalone'
  elsif turbo_frame_request?
    # For Turbo Frame requests, return just the edit row partial
    render partial: 'elaine_crud/base/edit_row', locals: { record: @record, columns: @columns }
  else
    # For direct access, render the full edit page showing all records with this one in edit mode
    render 'elaine_crud/base/edit'
  end
end

#indexObject

Standard CRUD actions



41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/controllers/elaine_crud/base_controller.rb', line 41

def index
  @records = fetch_records
  @model_name = crud_model.name
  @columns = determine_columns

  # Search/filter metadata
  @search_query = search_query
  @active_filters = filters
  @searchable_columns = determine_searchable_columns
  @filterable_columns = determine_filterable_columns
  @total_count = total_unfiltered_count if search_active?
end

#newObject



61
62
63
64
65
66
67
68
69
70
# File 'app/controllers/elaine_crud/base_controller.rb', line 61

def new
  @record = crud_model.new
  @model_name = crud_model.name

  # Pre-populate with parent relationship if filtering by parent
  populate_parent_relationships(@record)

  apply_field_defaults(@record)
  render 'elaine_crud/base/new'
end

#new_modalObject

Action for rendering new form in modal (for nested creates)



73
74
75
76
77
78
79
80
81
# File 'app/controllers/elaine_crud/base_controller.rb', line 73

def new_modal
  @record = crud_model.new
  @model_name = crud_model.name
  @modal_mode = true
  @return_field = params[:return_field]  # The foreign key field to update

  apply_field_defaults(@record)
  render 'elaine_crud/base/new_modal', layout: false
end

#showObject



54
55
56
57
58
59
# File 'app/controllers/elaine_crud/base_controller.rb', line 54

def show
  @record = find_record
  @model_name = crud_model.name
  @columns = determine_columns
  render 'elaine_crud/base/show'
end

#updateObject



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'app/controllers/elaine_crud/base_controller.rb', line 148

def update
  @record = find_record
  @model_name = crud_model.name
  @columns = determine_columns

  update_params = record_params

  # Debug logging for development
  if Rails.env.development?
    Rails.logger.info "ElaineCrud: Attempting to update with params: #{update_params.inspect}"
    Rails.logger.info "ElaineCrud: Record before update: #{@record.attributes.inspect}"
  end

  if @record.update(update_params)
    Rails.logger.info "ElaineCrud: Record updated successfully: #{@record.attributes.inspect}" if Rails.env.development?

    # For Turbo Frame requests, return the view row partial
    if turbo_frame_request?
      # Use bg-white for consistency when returning from edit (alternating colors handled by full page refresh)
      # Pass just_saved: true to trigger highlight animation
      render partial: 'elaine_crud/base/view_row', locals: { record: @record, columns: @columns, row_bg_class: 'bg-white', is_last_record: false, just_saved: true }
    else
      redirect_to polymorphic_path(@record), notice: "#{crud_model.name} was successfully updated.", status: :see_other
    end
  else
    # Handle validation errors
    Rails.logger.warn "ElaineCrud: Record update failed with errors: #{@record.errors.full_messages}" if Rails.env.development?

    if turbo_frame_request?
      # Return edit row partial with errors
      render partial: 'elaine_crud/base/edit_row', locals: { record: @record, columns: @columns }, status: :unprocessable_entity
    else
      # Render full edit page with errors - need search/filter metadata
      @records = fetch_records
      @search_query = search_query
      @active_filters = filters
      @searchable_columns = determine_searchable_columns
      @filterable_columns = determine_filterable_columns
      @total_count = total_unfiltered_count if search_active?
      render 'elaine_crud/base/edit', status: :unprocessable_entity
    end
  end
end