class ResourcesService attr_reader :model_klass, :model_fields def initialize(model_klass_name, model_fields) @model_klass = model_klass_name.constantize @model_fields = model_fields.map { |field_attributes| field_attributes[:field_name] } end def index_action(per_page, page, sort, query, model_attributes, reflection_tables, reflection_columns) per_page = per_page.to_i page = page.to_i if page.present? total = model_klass.count resources = model_klass.limit(per_page) if reflection_tables.present? resources = resources.includes(reflection_tables) model_fields.push(*reflection_columns) end if query.present? search_result = search(query, model_klass, model_attributes) resources = search_result[:resources] total = search_result[:total] end resources = resources.offset((per_page * page) - per_page) if page.present? resources = if sort.present? resources.order(sort[:column_name] => sort[:order]) else resources.order(id: :asc) end OpenStruct.new( resources: resources.pluck(*model_fields).map { |resource| model_fields.zip(resource).to_h }, total: total ) end private def search(search_query, model_klass, model_attributes) return [] if model_attributes.empty? query = model_attributes.map { |model_attribute| "#{model_attribute} LIKE ?" }.join(' OR ') query_arguments = model_attributes.map { "%#{search_query}%" } { resources: model_klass.where(query, *query_arguments), total: model_klass.where(query, *query_arguments).count } end end