https://avo.cool logo
Join Discord
Powered by
# tips-and-tricks
  • Hey
    p

    proud-breakfast-80041

    06/14/2024, 3:48 PM
    Hey i want to cofigure avo timezone globaly, so i did this config.timezone = 'EST' however it is not applied, and avo are showing datetime fields according to my local time ?
    l
    • 2
    • 3
  • Double errors
    p

    proud-breakfast-80041

    06/28/2024, 4:18 PM
    Hey i've a question about Avo forms when save is submitted with error the errors are duplicated in multiple flash messages , one says Validation fails: and lists all the error messages and then for each error message there is a another flash
    l
    • 2
    • 3
  • Hi avocados,
    l

    lively-ability-6202

    07/11/2024, 3:11 PM
    Hi avocados, Does anyone know if I can make certain sortable as a conditional to only show on All resource scope?
    l
    • 2
    • 10
  • Hi there, I work on an analytics
    m

    mammoth-xylophone-46880

    07/24/2024, 10:25 AM
    Hi there, I work on an analytics dashboard with multiple filters/ranges, how can I handle various filters for each card, also want to set dashboard-wide ranges. after that is there any way to extract all the cards data? thanks in advance.
    w
    w
    • 3
    • 14
  • Hi, Maybe someone knows a trick to remove the quotes and render embedded html fully?
    l

    lively-ability-6202

    07/25/2024, 1:43 PM
    Copy code
    ruby
    field :revenue_share_breakdown, as: :text, as_html: true, only_on: :show do
             record.bookkeeping_explanation(:owner)
    end
    Copy code
    ruby
    def     revenue_share_breakdown(_rows)
              erb_template = Rails.root.join('app/views/clients/accounts/transactions/_revenue_share_breakdown.html.erb').read
              formatted_html = ERB.new(erb_template).result(binding)
              formatted_html.gsub(/\n+/, '')
    end
    https://cdn.discordapp.com/attachments/1266027985484648489/1266027998990176276/image.png?ex=66a3a7f4&is=66a25674&hm=2c851c17e96c239f0a88f39564ce7111fafd1d29216e6a2a13cac03a0173a750&
    l
    • 2
    • 3
  • Hi avocados \o, do you know if it's
    l

    lively-ability-6202

    08/28/2024, 8:43 AM
    Hi avocados \o, do you know if it's possible to activate autocomplete on the dropdown filters?
    l
    • 2
    • 5
  • By adding the following Controller, you
    s

    straight-pager-31449

    08/30/2024, 2:05 PM
    By adding the following Controller, you can now navigate pages using the left(←) and right(→) arrow keys on the keyboard. This feature was added based on a user request, and I’ll monitor the response over time.
    l
    • 2
    • 3
  • I fixed an issue that occurred when
    s

    straight-pager-31449

    08/31/2024, 6:01 AM
    I fixed an issue that occurred when there were multiple pagers or tabs. With the following code, it will work on the currently displayed pager, even if there are multiple pager buttons or tabs. > By adding the following Controller, you can now navigate pages using the left(←) and right(→) arrow keys on the keyboard. This feature was added based on a user request, and I’ll monitor the response over time.
    f
    • 2
    • 6
  • Gentlemen, do you know if it's possible
    l

    lively-ability-6202

    10/14/2024, 1:43 PM
    Gentlemen, do you know if it's possible to show horizontal scrolling in the tables on the Index view? Would help Windows users a lot https://cdn.discordapp.com/attachments/1125160641569771550/1295381553597255793/image.png?ex=670e7195&is=670d2015&hm=e184681565eefa60cc98e6d0561d332f232877af75d3d94d9ecceabf8a0d52d3&
    f
    l
    • 3
    • 16
  • Associations pagination
    s

    straight-pager-31449

    11/22/2024, 2:00 AM
    @loud-jewelry-99127 Thank you for always updating Avo. If there is a function like that, I would like to know about it. Is it possible to change the default value of config.per_page to 6, etc., only for the has_many of the show screen of a specific resource? Also, if you want to implement it like that, what approach is suitable? > config.per_page = 12 > config.per_page_steps = [6, 12, 18] > config.via_per_page = 12
    l
    • 2
    • 12
  • As a countermeasure for Global Search
    s

    straight-pager-31449

    11/24/2024, 5:43 AM
    As a countermeasure for Global Search load, using caching in the search_results method of the SearchController class and utilizing the DB Reader significantly improves performance. While the Controller already separates access for read/write operations, applying the same approach to Global Search has made it even more efficient and user-friendly.
    l
    • 2
    • 1
  • When using a composite key consisting of
    s

    straight-pager-31449

    12/05/2024, 3:28 PM
    When using a composite key consisting of a timestamp like created_at and an id starting with an underscore, various errors can occur. Including and executing the process in the following class can help resolve these issues. Although it's a rare case, you should be cautious when using partitioned tables for handling large data volumes. - Example of an id:
    2024-11-20 22:41:00 +0000___foobarid
    Copy code
    class CompositePrimaryKeyFormatter
      def self.format(id)
        return id if id.is_a?(Array)
    
        if id.match?(/\+\d{4}/) && id.include?('__') && (match = id.match(/(\+\d{4})/))
          timestamp = "#{match.pre_match}+0900"
          rest = match.post_match.strip.sub(/^_/, '')
          [timestamp, rest]
        else
          id
        end
      end
    end
    This is likely better approached using a different method, but it is documented here as a temporary workaround.
    l
    • 2
    • 3
  • Download your index view as CSV
    c

    cool-minister-27228

    12/11/2024, 4:04 PM
    generic download action for your resources that will take all visible data in the index view, generate the csv header from the first entry, map all values and generate a csv file to download. DISCLAIMER: It uses a lot of internal and private APIs. Keep in mind that this code can be broken if something is changed internally. Use it with care 😉 TLDR; Download your index view as CSV
    Copy code
    ruby
    class Avo::Actions::ExportCsv < Avo::BaseAction
      self.name = "Export all data as CSV"
      self.standalone = true
      self.may_download_file = true
    
      def handle(query:, fields:, current_user:, resource:, **args)
        records = resource.class.query_scope
        resource.hydrate(view: "index")
    
        resources = records.map do |record|
          resource.dup.hydrate(record: record)
        end
    
        return error 'No records to export' if resources.empty?
    
        csv = CSV.generate do |csv|
          first_resorce = resources.first
          first_resorce.detect_fields
          header_fields = first_resorce.get_fields(reflection: nil, only_root: true).reject{ |field|field.id == :preview }
    
          csv << header_fields.map(&:name)
    
          resources.each do |resource_row|
            resource_row.detect_fields
    
            row_fields = resource_row.get_fields(reflection: nil, only_root: true).reject{ |field|field.id == :preview }
    
            csv << row_fields.map do |field|
              if field.value.is_a?(ApplicationRecord)
                Avo.resource_manager.get_resource_by_model_class(field.value.class).new(record: field.value).record_title
              else
                field.value
              end
            end
          end
        end
        download csv, "#{resource.name.downcase.pluralize}_#{ Time.now.strftime('%Y-%m-%d_%H-%M-%S') }.csv"
      end
    end
    l
    l
    • 3
    • 2
  • s

    straight-pager-31449

    01/10/2025, 1:43 AM
    I wanted to display a count in pagination, but since the query for counting records was a slow query due to a large number of records, I implemented the following temporary solution. Since overriding from the Controller wasn’t possible, I addressed the issue using the following approach:
    Copy code
    - config/initializers/avo.rb
    Avo.configure do |config|
      Rails.configuration.to_prepare do
        Pagy::Backend.prepend(CustomPagyBackend)
    Copy code
    module CustomPagyBackend
      private
    
    # override the pagy_get_count method adding
    # the Rails.cache wrapper around the count call
    def pagy_get_count(collection, _vars)
      cache_key = "pagy-#{collection.model.name}:#{collection.to_sql}"
      Rails.cache.fetch(cache_key, expires_in: 20 * 60) do
        collection.count(:all)
      end
    end
    > cache the count https://ddnexus.github.io/pagy/docs/how-to/#deal-with-a-slow-collection-count
  • m

    millions-exabyte-27721

    01/10/2025, 6:40 AM
    Incidentally I’ve got a blog post coming up for that exact problem very soon!
  • Optimize Pagination Speed with Asynchron...
    m

    millions-exabyte-27721

    02/03/2025, 5:44 PM
    If took some time, but here’s that post: https://www.rorvswild.com/blog/2025/optimize-pagination-speed-with-asynchronous-queries-in-ruby-on-rails
    l
    • 2
    • 2
  • s

    straight-pager-31449

    02/18/2025, 11:31 AM
    Due to a problem with Pagy, limit is currently not working even for avo. If you have written the following code, you might want to be careful.
    Copy code
    field :foo, as: :has_many, scope: -> {
          query.limit(3) # limit does not work
        }
    https://discord.com/channels/740892036978442260/1340959611410448415/1341370592196034621
  • This is a code to solve the problem that
    s

    straight-pager-31449

    02/21/2025, 5:13 PM
    This is a code to solve the problem that pressing enter while typing in a Dynamic filter form in a language that uses the IME causes the apply button to be immediately pressed and filtered, instead of converting the character.
    Copy code
    // Global listener to intercept Enter key events during IME composition.
    // This prevents unwanted "apply" actions when confirming input via an IME
    document.addEventListener(
      "keydown",
      (event) => {
        // If the key is not "Enter" or IME is not composing, exit early.
        if (event.key !== "Enter" || !event.isComposing) return;
        event.stopImmediatePropagation();
      },
      true // Use capture phase to intercept the event as early as possible.
    );
    l
    • 2
    • 3
  • Hi avocados,
    l

    lively-ability-6202

    02/24/2025, 8:47 AM
    Hi avocados, Do you know how can I make the cards work when page is opened via association?
    l
    • 2
    • 6
  • Folks, I am trying to create what I
    f

    flaky-room-51691

    02/27/2025, 3:36 PM
    Folks, I am trying to create what I believe is a "simple" dynamic filter. I have a resource called Errors with a relationwith with the model professional. I want to have a filter where I select a professional by using a autocomplete search to select the professinal, since I have too many professionals to list in a single select with the "fetch_values_from". I did not find this in the documentation, but I would love to know if you did this recently. Thank you. Maybe it's related to this issue? https://discord.com/channels/740892036978442260/1278273800894414918
    l
    • 2
    • 42
  • Is there a way to disable avo resource
    f

    future-match-90639

    03/03/2025, 6:30 PM
    Is there a way to disable avo resource generation on scaffolds? I found
    skip-avo-resource
    , but it would be on an individual scaffold. I was thinking of
    /initializers/avo.rb
    /
    self.skip_scaffolds = true
    l
    l
    • 3
    • 5
  • The following method is useful when you
    s

    straight-pager-31449

    03/31/2025, 2:41 PM
    The following method is useful when you want to define the name, description, and query of a scope in the scope caller. it is possible to change the contents of a query by passing name, description, and query_value from the caller of the Scope with the same query. There may be a better way, but the following code has been confirmed to work. (avo v3.18.1)
    Copy code
    class Avo::Resources::User < ...
      ...
      def custom_my_scope(name:, description:, query_value:)
        klass = Class.new(Avo::Advanced::Scopes::BaseScope) do
          self.name = -> { name }
          self.description = "this is #{description} scope"
          self.scope = -> { query.where(foobar: query_value) }
        end
    
        # Create a unique constant name based on the provided name and query_key
        const_name = "CustomMyScope_#{name.gsub(/\s+/, '')}_#{query_value}".gsub(/[^A-Za-z0-9_]/, '')
        Object.const_set(const_name, klass)
      end
    
      def scopes
        scope custom_my_scope(name: 'foo1', description: 'foo1 description', query_value: 'user')
        scope custom_my_scope(name: 'foo2', description: 'foo2 description', query_value: 'admin')
        scope custom_my_scope(name: 'foo3', description: 'foo3 description', query_value: 'blocked')
        ...
    l
    • 2
    • 1
  • s

    straight-pager-31449

    04/10/2025, 8:36 AM
    This is a method for confirm tag input in the Dynamic filterTags field by using the space key. https://discord.com/channels/740892036978442260/1357750611063607367/1359808531712442531
  • s

    straight-pager-31449

    04/15/2025, 2:37 PM
    This is sample code for sticky table headers on index view. https://discord.com/channels/740892036978442260/1361688145418129559/1361709965882167326
  • l

    lemon-wall-20836

    04/24/2025, 7:29 AM
    Has anyone tried flatware? we're looking to make our rspec tests faster and would love some confirmation from someone who used it and was successful https://github.com/briandunn/flatware
  • devise masquerade (impersonate/login as)...
    f

    future-match-90639

    06/06/2025, 9:56 AM
    I'm trying to add devise masquerade (login as) from Avo.
    masquerade_path(record)
    isn't working. I found a workaround but it looks awful. What should I do? PR here: https://github.com/yshmarov/moneygun/pull/275
    l
    • 2
    • 15
  • https://docs.avohq.io/3.0/records-
    f

    future-match-90639

    07/10/2025, 11:40 AM
    https://docs.avohq.io/3.0/records-reordering.html#reorder-using-drag-and-drop Just wanted to say thank you for adding drag & drop ordering! So much more comfortable than arrows for ordering https://cdn.discordapp.com/attachments/1125160641569771550/1392832931717845062/Screenshot_2025-07-10_at_13.34.50.png?ex=6870f840&is=686fa6c0&hm=01f34c73f708d099fe8791a54ab0201c4f4aa6763f062d37890abfa9c41418d1&
    l
    • 2
    • 4
  • GitHub - active-hash/active_hash: A read...
    f

    future-match-90639

    07/15/2025, 2:51 PM
    https://docs.avohq.io/3.0/array-resources.html#creating-an-array-resource Array resources arrived just in time! My application is using https://github.com/active-hash/active_hash for some non-database backed resources. Perfect usecase! https://cdn.discordapp.com/attachments/1125160641569771550/1394692827463684239/Screenshot_2025-07-15_at_16.50.10.png?ex=6878652a&is=687713aa&hm=99e525ccf397e847ff786114ec91a8d2c44271d0371eda0792015a782a5b4e4a&
    l
    • 2
    • 3
  • woohoo!!! I have tom-select multiple:{}
    f

    future-match-90639

    07/15/2025, 7:13 PM
    woohoo!!! I have tom-select multiple:{} working with avo the resource:
    Copy code
    def fields
        with_options(only_on: [:index, :show, :edit]) do
          field :category_ids,
            as: :select,
            multiple: true,
            options: -> { Category.options_for_select },
            html: {edit: {wrapper: {style: "margin-bottom: 13rem;"}, input: {data: {controller: "avo-tom_select"}}}}
        end
    app/javascript/controllers/avo/tom_select_controller.js
    Copy code
    import { Controller } from '@hotwired/stimulus'
    import TomSelect from 'tom-select'
    import 'tom-select/dist/css/tom-select.css'
    
    export default class extends Controller {
      connect() {
        console.log('tom-select controller connected')
        if (!this.element.tomSelect) {
          new TomSelect(this.element, {
            plugins: ['remove_button'],
            create: false,
            maxItems: null,
            searchField: ['text']
          })
        }
      }
    }
    app/views/avo/partials/_head.html.erb
    Copy code
    <%= stylesheet_link_tag "avo.custom", media: "all", "data-turbo-track": "reload" %>
    <%= javascript_include_tag "avo.custom", "data-turbo-track": "reload", defer: true %>
    https://cdn.discordapp.com/attachments/1125160641569771550/1394758741966065837/Screenshot_2025-07-15_at_21.10.54.png?ex=6877f9cd&is=6876a84d&hm=6df105c46c1ce3a0d0a2afbc7a216114b693b87ce3e7295687f728e0ee9442b2&
    l
    l
    • 3
    • 3
  • Customisable dynamic filters in Avo (htt...
    l

    lively-ability-6202

    07/17/2025, 1:58 AM
    For all avocados who want to empower dynamic filters: https://gist.github.com/maokomioko/b88f9a6ef6dfc611034e44042f9e857d
    l
    • 2
    • 2