Upgrade guide
We'll update this page when we release new Avo 3 versions.
If you're looking for the Avo 2 to Avo 3 upgrade guide, please visit the dedicated page.
Upgrade from 3.16.1 to 3.16.2
-> markdown renamed to easy_mde
We added a new GitHub-inspired markdown
field which supports ActiveStorage and gives us better control over the whole experience.
This lead to us renaming the old markdown
field to easy_mde
and naming this new one markdown
. If you'd like your app to work the same as before, rename all your :markdown
field to :easy_mde
. Otherwise leave them like that and enjoy the new field.
Upgrade from 3.15.3 to 3.15.4
The config.cache_resource_filters
option is now obsolete and has been replaced with config.persistence
. If you previously had:
config.cache_resource_filters = true
You should update your configuration to:
config.persistence = { driver: :session }
This updated setting preserves the same behavior, ensuring resource filters and association pagination states persist across requests for a consistent user experience. For additional details, refer to the persistence
documentation.
Persistent Pagination Behavior
By default, pagination settings for associations are no longer stored in the session. If your application requires persistent pagination, you must explicitly enable the persistence
configuration:
Avo.configure do |config|
config.persistence = { driver: :session }
end
WARNING
Important: When enabling this feature, it is strongly recommended to update the session store to avoid potential cookie overflow errors. The default Rails cookie store has a size limit of 4096 bytes, and persisting multiple pagination states or filters can exceed this limit. For more information, refer to the persistence
configuration documentation.
Upgrade from 3.14.0 to 3.14.1
We’ve introduced the associations_lookup_list_limit
configuration option to prevent crashing when listing associations on large collections. The new default limit is set to a 1000
records.
config.associations_lookup_list_limit = 1000
Upgrade from 3.13.6 to 3.13.7
The implicit_authorization
option has been renamed to explicit_authorization
to better align with the feature's functionality. The underlying logic remains unchanged, so you only need to perform a rename if you're already using it.
config.implicit_authorization = true
config.explicit_authorization = true
Upgrade from 3.13.3 to 3.13.4
-> implicit_authorization
We’ve introduced the implicit_authorization
configuration option to enhance the security of your applications. This option allows you to define how missing policy classes or methods are handled. When set to true
, any action without an explicitly defined policy will automatically be denied, ensuring that unprotected actions are not unintentionally accessible. This new behavior offers a more secure approach for authorization.
For new applications, implicit_authorization
is enabled by default, but existing applications will retain the legacy behavior (false
), allowing missing policies or methods to authorize actions. We encourage you to adopt this new setting by enabling implicit_authorization
, as it provides greater control over your authorization flow and reduces the risk of unauthorized access due to missing policies. Before enabling it, be sure to review your policy classes to ensure all necessary methods are defined, preventing any unintended access restrictions.
We highly recommend taking a moment to read through the entire implicit_authorization
documentation section before making any changes. Understanding this feature is crucial to ensuring your application's security and functionality, so don’t skip it!
Upgrade from 3.11.7 to 3.11.8
-> Dynamic filters query
query
is specified on a dynamic filter.Upgrade from 3.10.10 to 3.11.3
-> Unexpected behavior
However, if the browser already has this cookie from a previous interaction, the issue does not occur.This issue is resolved Since v3.11.3, so we recommend updating directly to that version.
Upgrade from 3.10.9 to 3.10.10
-> Array filter
Custom dynamic filter type array
was duplicated and is now obsolete in favor of tags
.
def filters
dynamic_filter :the_filter,
type: :array
type: :tags
Upgrade from 3.10.6 to 3.10.7
-> Boolean field
In versions lower than 3.10.6, boolean fields with a nil
value were represented by a red X, which could be misleading. Since v3.10.7 when a boolean field has a nil
value, it is displayed with a dash (—
) instead of a red X.
Upgrade from 3.10 to 3.11
Actions no longer need to be registered inside actions method
Actions inside customizable blocks no longer need to be declared in the actions
method.
# Before
class Avo::Resources::Fish < Avo::BaseResource
self.title = :name
self.show_controls = -> do
# In order to use it here
action Avo::Actions::ReleaseFish, style: :primary, color: :fuchsia, arguments: {
action_on_show_controls: "Will use this arguments"
}
end
# 👇 Also declare it here 👇
def actions
action Avo::Actions::ReleaseFish, style: :primary, color: :fuchsia, arguments: {
action_on_show_controls: "Will use this arguments"
}
end
end
# After
class Avo::Resources::Fish < Avo::BaseResource
self.title = :name
self.show_controls = -> do
# In order to use it here
action Avo::Actions::ReleaseFish, style: :primary, color: :fuchsia, arguments: {
action_on_show_controls: "Will use this arguments"
}
end
# 👇 No need to declare it here 👇
def actions
end
end
Upgrade from 3.9.2 to 3.10
Deprecated fetch_labels
option in favor of format_using
on tags field.
Upgrade from 3.9.1 to 3.9.2
We tweaked the way locales
and i18n work with Avo. In theory nothing should change in your setup, but please read the guide once more to see how it works.
Upgrade from 3.7.4 to 3.9.1
Update to Rails 7.2 or greater
Rails 7.1 has a bug (explanation) which would break path helpers for nested mounted engines.
Steps to update
- Update
avo
,avo-pro
, oravo-advanced
to version3.9.1
- Update
rails
to at least7.2.0.beta2
(or greater when available) - Run
bundle update rails avo-advanced
# Gemfile
# Use Rails 7.2 or greater
gem "rails", ">= 7.2.0.beta2"
# or
# You can also run off `main`
gem "rails", github: "rails/rails", branch: "main"
# Update Avo
gem "avo-advanced", ">= 3.9.1"
# Use `ransack` version `4.2.0` for searching
gem "ransack", ">= 4.2.0"
# This version of acts-as-taggable-on is compatible with
# Follow this PR to get the fix in the library
# https://github.com/mbleigh/acts-as-taggable-on/pull/1126
gem "acts-as-taggable-on", github: "avo-hq/acts-as-taggable-on"
bundle update rails avo-advanced
Skip versions 3.8.x and 3.9.0
From Avo 3.7.4 you should update straight to 3.9.1
. The other intermediary versions introduced a bug when we tried to improve support for Rails 7.1+
More on that on this issue.
Upgrade from 3.6.1 to 3.6.2
-> Cache
Versions 3.6.2
/ 3.6.3
have some issues around cache, we recommend to upgrade directly to 3.6.4
.
Upgrade from 3.5.4 to 3.5.5
-> Record errors
before_update do
if validation_fail?
errors.add(:field_id, "Error message")
end
end
Upgrade from 3.4.2 to 3.4.3
-> turbo configuration
config.turbo = {
instantclick: true
instant_click: true
}
Upgrade from 3.4.1 to 3.4.2
-> Basic Filters URL param changed to encoded_filters
This is not what we intended.
To fix this we are changing the URL param of the Basic Filters from filters
to encoded_filters
so now you can have a URL with both filters.
# Before
https://example.com/avo/resources/users?filters[first_name][contains][]=Jason&page=1&filters=eyJBdm86OkZpbHRlcnM6OklzQWRtaW4iOlsiYWRtaW5zIl19
# After
https://example.com/avo/resources/users?filters[first_name][contains][]=Jason&page=1&encoded_filters=eyJBdm86OkZpbHRlcnM6OklzQWRtaW4iOlsiYWRtaW5zIl19
What to do?
If you have hardcoded links where you reference the filters
param, change that to encoded_filters
. These links might be in Tools, Resource Tools, Menu Items, or regular view partials (yes, basically anywhere you might have added them 🫤).
A quick search through your codebase should reveal them.
-> Add active_record_extended gem to your Gemfile
This gem uses postgres and was breaking for those who use any other database like sqlite
.
If you want to keep Contained in
option on arrays and tags filters you should include the active_record_extended
gem to your Gemfile
.
-> Multiple action flux
If you have a multiple action flux implemented with redirect_to
you should change it to navigate_to_action
.
-> Action link_arguments method
field :name,
as: :text,
filterable: true,
name: "name (click to edit)",
only_on: :index do
arguments = Base64.encode64 Avo::Services::EncryptionService.encrypt(
message: {
cities: Array[resource.record.id],
render_name: true
},
purpose: :action_arguments
)
arguments = {
cities: Array[resource.record.id],
render_name: true
}
path, data = Avo::Actions::City::Update.link_arguments(
resource: resource,
arguments: arguments
)
link_to resource.record.name, path, data: data
end
</Option>
<Option name="`resource.record` or `record` as `nil` on visibility blocks">
You may notice that `resource.record == nil` on some visibility blocks. That happens when evaluating the field visibility to render header columns. On index, there is no record.
This is a consequence of a bug fix where `resource.record` was wrongly storing the last record of the index table.
Check [this discussion](https://github.com/avo-hq/avo/issues/2544) for more details
</Option>
## Upgrade from 3.3.0 to 3.4.0
Ruby 3.0 is end-of-life and we pushed some code that only works with Ruby 3.1.
## Upgrade from 3.2.2 to 3.3.0
<Option name="`may_download_file` deprecated">
Actions now fully operate with turbo leading to the deprecation of `may_download_file` option. It can be safely removed from all actions.
</Option>
<Option name="Status field `failed_when` and `loading_when` default to and empty array">
We found [some issues](https://github.com/avo-hq/avo/pull/2316) with declaring defaults to `failed_when` and `loading_when` field options so we are now defaulting them to empty arrays.
If you need that behavior back, add it to your fields.
```ruby{3,4}
field :status,
as: :status,
failed_when: [:failed],
loading_when: [:waiting, :running]
-> Scopes namespace change
-> TailwindCSS integration
/* app/assets/stylesheets/avo/avo.tailwind.css */
@import '../../../../tmp/avo/base.css'; // [!code --]
@import '../../../../tmp/avo/avo.base.css';
Upgrade from 3.1.3 to 3.1.4
-> Avo::Filters::BaseFilter.decode_filters
Upgrade from 3.0.1.beta24 to 3.0.2
-> Sidebar should be declared inside a panel
We suggest to read panels and sidebars sections for more information and to be aware of the new possibilities.
-> Dashboards visibility and authorization
This behavior has been enhanced. Now, even if visible
is set to false
, the dashboard remains accessible but won't appear in the menu. Additionally, if authorize
returns false
, the dashboards are now hidden.
-> Actions
-> Attachments eager load
Attachments are no longer automatically eager loading. If you want to eager load attachments there are at least two ways:
Use self.includes
option
class Avo::Resources::PhotoComment < Avo::BaseResource
self.includes = [:user, [photo_attachment: :blob]]
def fields
field :user, as: :belongs_to
field :photo, as: :file, is_image: true
end
Use self.index_query
option
class Avo::Resources::Product < Avo::BaseResource
self.index_query = -> {
query.includes image_attachment: :blob
}
def fields
field :image, as: :file, is_image: true
end
Upgrade from 3.0.1.beta23 to 3.0.1.beta24
-> Cards
# Before
class Avo::Cards::AmountRaised < Avo::Dashboards::MetricCard
class Avo::Cards::ExampleAreaChart < Avo::Dashboards::ChartkickCard
class Avo::Cards::ExampleBarChart < Avo::Dashboards::ChartkickCard
# ...
# After
class Avo::Cards::AmountRaised < Avo::Cards::MetricCard
class Avo::Cards::ExampleAreaChart < Avo::Cards::ChartkickCard
class Avo::Cards::ExampleBarChart < Avo::Cards::ChartkickCard
# ...
Upgrade from 3.0.1.beta22 to 3.0.1.beta23
-> Caching
One of our concerns was to maintain the status quo, but if you notice any caching issues there is a new configurable option config.cache_store
that allows you to tell Avo what cache_store
to use.
Check cache page for more details.
Upgrade from 3.0.1.beta8 to 3.0.1.beta9
-> Heading as field
For more information about heading
field syntax check heading
field's documentation.
heading "personal information"
heading "contact"
heading '<div class="underline uppercase font-bold">DEV</div>', as_html: true
field :personal_information, as: :heading # data-field-id == "personal_information"
field :heading, as: :heading, label: "Contact" # data-field-id == "heading"
field :dev, as: :heading, as_html: true, label: '<div class="underline uppercase font-bold">DEV</div>'
-> Badge field secondary option renamed to neutral
field :stage,
as: :badge,
options: {
info: [:discovery, :idea],
success: :done,
warning: "on hold",
danger: :cancelled,
neutral: :drafting
}
:::
-> Rename link_to_resource to link_to_record
class Avo::Resources::User < Avo::BaseResource
def fields
field :id, as: :id, link_to_record: true
field :email, as: :gravatar, link_to_record: true
end
end
Upgrade from 3.0.1.beta5 to 3.0.1.beta6
-> The status field changed behavior
# Before
field :status,
as: :status,
failed_when: :failed,
loading_when: :loading
# After
field :status,
as: :status,
failed_when: :failed,
loading_when: :loading
success_when: :deployed # specify the success state