class Avo::BaseController
def applied_filters
def applied_filters if params[:filters].present? return JSON.parse(Base64.decode64(params[:filters])) end filter_defaults = {} @resource.get_filters.each do |filter_class| filter = filter_class.new if filter.default.present? filter_defaults[filter_class.to_s] = filter.default end end filter_defaults end
def applied_filters_cache_key
def applied_filters_cache_key "avo.base_controller.#{@resource.route_key}.applied_filters" end
def cache_applied_filters
def cache_applied_filters ::Avo::App.cache_store.delete applied_filters_cache_key if params[:filters].nil? ::Avo::App.cache_store.write(applied_filters_cache_key, params[:filters], expires_in: 7.days) end
def cast_nullable(params)
def cast_nullable(params) fields = @resource.get_field_definitions nullable_fields = fields.filter do |field| field.nullable end .map do |field| [field.id, field.null_values] end .to_h params.each do |key, value| nullable = nullable_fields[key.to_sym] if nullable.present? && value.in?(nullable) params[key] = nil end end params end
def create
def create @model = @resource.fill_model(@resource.model_class.new, cast_nullable(model_params)) saved = @model.save @resource.hydrate(model: @model, view: :new, user: _current_user) respond_to do |format| if saved redirect_path = if params[:via_relation_class].present? && params[:via_resource_id].present? resource_path(params[:via_relation_class].safe_constantize, resource_id: params[:via_resource_id]) else resource_path(@model) end format.html { redirect_to redirect_path, notice: "#{@model.class.name} was successfully created." } format.json { render :show, status: :created, location: @model } else flash[:error] = t "avo.you_missed_something_check_form" format.html { render :new, status: :unprocessable_entity } format.json { render json: @model.errors, status: :unprocessable_entity } end end end
def destroy
def destroy @model.destroy! respond_to do |format| format.html { redirect_to params[:referrer] || resources_path(@model, turbo_frame: params[:turbo_frame], view_type: params[:view_type]), notice: t("avo.resource_destroyed", attachment_class: @attachment_class) } format.json { head :no_content } end end
def edit
def edit @resource = @resource.hydrate(model: @model, view: :edit, user: _current_user) @page_title = @resource.default_panel_name # If we're accessing this resource via another resource add the parent to the breadcrumbs. if params[:via_resource_class].present? && params[:via_resource_id].present? via_resource = Avo::App.get_resource_by_model_name params[:via_resource_class] via_model = via_resource.class.find_scope.find params[:via_resource_id] via_resource.hydrate model: via_model add_breadcrumb via_resource.plural_name, resources_path(via_resource.model_class) add_breadcrumb via_resource.model_title, resource_path(via_model) else add_breadcrumb resource_name.humanize, resources_path(@resource.model_class) end add_breadcrumb @resource.model_title, resource_path(@resource.model) add_breadcrumb t("avo.edit").humanize end
def index
def index @page_title = resource_name.humanize add_breadcrumb resource_name.humanize set_index_params set_filters set_actions # If we don't get a query object predefined from a child controller like relations, just spin one up unless defined? @query @query = @resource.class.query_scope end # Remove default_scope for index view if @resource.unscoped_queries_on_index @query = @query.unscoped end # Eager load the relations if @resource.includes.present? @query = @query.includes(*@resource.includes) end # Eager load the active storage attachments @query = eager_load_files(@resource, @query) # Sort the items if @index_params[:sort_by].present? unless @index_params[:sort_by].eql? :created_at @query = @query.unscope(:order) end @query = @query.order("#{@resource.model_class.table_name}.#{@index_params[:sort_by]} #{@index_params[:sort_direction]}") end # Apply filters applied_filters.each do |filter_class, filter_value| @query = filter_class.safe_constantize.new.apply_query request, @query, filter_value end @pagy, @models = pagy(@query, items: @index_params[:per_page], link_extra: "data-turbo-frame=\"#{params[:turbo_frame]}\"", size: [1, 2, 2, 1]) # Create resources for each model @resources = @models.map do |model| @resource.hydrate(model: model, params: params).dup end end
def model_params
def model_params request_params = params.require(model_route_key).permit(permitted_params) if @resource.devise_password_optional && request_params[:password].blank? && request_params[:password_confirmation].blank? request_params.delete(:password_confirmation) request_params.delete(:password) end request_params end
def model_route_key
def model_route_key @resource.model_class.model_name.route_key.singularize end
def new
def new @model = @resource.model_class.new @resource = @resource.hydrate(model: @model, view: :new, user: _current_user) @page_title = @resource.default_panel_name add_breadcrumb resource_name.humanize, resources_path(@resource.model_class) add_breadcrumb t("avo.new").humanize end
def permitted_params
def permitted_params @resource.get_field_definitions.select(&:updatable).map(&:to_permitted_param) end
def reset_pagination_if_filters_changed
def reset_pagination_if_filters_changed params[:page] = 1 if params[:filters] != ::Avo::App.cache_store.read(applied_filters_cache_key) end
def set_actions
def set_actions if params[:resource_id].present? model = @resource.class.find_scope.find params[:resource_id] end @actions = @resource.get_actions.map do |action| action.new(model: model, resource: @resource) end end
def set_filters
def set_filters @filters = @resource.get_filters.map do |filter_class| filter = filter_class.new filter end end
def set_index_params
def set_index_params @index_params = {} # Pagination @index_params[:page] = params[:page] || 1 @index_params[:per_page] = Avo.configuration.per_page if cookies[:per_page].present? @index_params[:per_page] = cookies[:per_page] end if @parent_model.present? @index_params[:per_page] = Avo.configuration.via_per_page end if params[:per_page].present? @index_params[:per_page] = params[:per_page] cookies[:per_page] = params[:per_page] end # Sorting if params[:sort_by].present? @index_params[:sort_by] = params[:sort_by] elsif @resource.model_class.present? && @resource.model_class.column_names.include?("created_at") @index_params[:sort_by] = :created_at end @index_params[:sort_direction] = params[:sort_direction] || :desc # View types @index_params[:view_type] = params[:view_type] || @resource.default_view_type || Avo.configuration.default_view_type @index_params[:available_view_types] = @resource.available_view_types end
def show
def show set_actions @resource = @resource.hydrate(model: @model, view: :show, user: _current_user, params: params) @page_title = @resource.default_panel_name # If we're accessing this resource via another resource add the parent to the breadcrumbs. if params[:via_resource_class].present? && params[:via_resource_id].present? via_resource = Avo::App.get_resource_by_model_name params[:via_resource_class] via_model = via_resource.class.find_scope.find params[:via_resource_id] via_resource.hydrate model: via_model add_breadcrumb via_resource.plural_name, resources_path(via_resource.model_class) add_breadcrumb via_resource.model_title, resource_path(via_model) else add_breadcrumb resource_name.humanize, resources_path(@resource.model_class) end add_breadcrumb @resource.model_title end
def update
def update @model = @resource.fill_model(@model, cast_nullable(model_params)) saved = @model.save @resource = @resource.hydrate(model: @model, view: :edit, user: _current_user) respond_to do |format| if saved format.html { redirect_to params[:referrer] || resource_path(@model), notice: "#{@model.class.name} was successfully updated." } format.json { render :show, status: :ok, location: @model } else flash[:error] = t "avo.you_missed_something_check_form" format.html { render :edit, status: :unprocessable_entity } format.json { render json: @model.errors, status: :unprocessable_entity } end end end