From 148c269edee9d65d7aae982ec03ee5c521d477fd Mon Sep 17 00:00:00 2001 From: Paul Bob Date: Mon, 7 Aug 2023 18:31:40 +0300 Subject: [PATCH 1/3] more updates --- docs/.vitepress/config.js | 32 ++++++++++++------------ docs/3.0/actions.md | 2 +- docs/3.0/associations.md | 16 ++++++------ docs/3.0/custom-fields.md | 34 ++++++++++++++------------ docs/3.0/customization.md | 4 +-- docs/3.0/field-options.md | 2 +- docs/3.0/localization.md | 18 ++++++++------ docs/3.0/menu-editor.md | 5 ++-- docs/3.0/resource-tools.md | 28 ++++++++++++--------- docs/3.0/resources.md | 8 +++--- docs/3.0/stimulus-integration.md | 42 +++++++++++++++++--------------- 11 files changed, 103 insertions(+), 88 deletions(-) diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index e64b9c33..ae557f67 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -157,15 +157,15 @@ const config = { { text: "Customize Avo", items: [ - // {text: "Customization options", link: "/3.0/customization"}, + {text: "Customization options", link: "/3.0/customization"}, {text: "Grid view", link: "/3.0/grid-view"}, {text: "Map view", link: "/3.0/map-view"}, {text: "Custom view types", link: "/3.0/custom-view-types"}, - // {text: "Menu editor", link: "/3.0/menu-editor"}, + {text: "Menu editor", link: "/3.0/menu-editor"}, {text: "Search", link: "/3.0/search"}, - // {text: "Actions", link: "/3.0/actions"}, - // {text: "Localization (I18n)", link: "/3.0/localization"}, - // {text: "Branding", link: "/3.0/branding"}, + {text: "Actions", link: "/3.0/actions"}, + {text: "Localization (I18n)", link: "/3.0/localization"}, + {text: "Branding", link: "/3.0/branding"}, ], }, { @@ -177,17 +177,17 @@ const config = { // {text: "Advanced filters", link: "/3.0/filters/advanced-filters"}, ], }, - // { - // text: "Custom content", - // items: [ - // {text: "Custom views", link: "/3.0/custom-tools"}, - // {text: "Custom fields", link: "/3.0/custom-fields"}, - // {text: "Resource tools", link: "/3.0/resource-tools"}, - // {text: "Stimulus JS integration", link: "/3.0/stimulus-integration"}, - // {text: "Evaluation hosts", link: "/3.0/evaluation-hosts"}, - // {text: "Custom asset pipeline", link: "/3.0/custom-asset-pipeline"}, - // ], - // }, + { + text: "Custom content", + items: [ + {text: "Custom views", link: "/3.0/custom-tools"}, + {text: "Custom fields", link: "/3.0/custom-fields"}, + {text: "Resource tools", link: "/3.0/resource-tools"}, + {text: "Stimulus JS integration", link: "/3.0/stimulus-integration"}, + // {text: "Evaluation hosts", link: "/3.0/evaluation-hosts"}, + {text: "Custom asset pipeline", link: "/3.0/custom-asset-pipeline"}, + ], + }, // { // text: "Native Avo components", // items: [ diff --git a/docs/3.0/actions.md b/docs/3.0/actions.md index 9f606a90..a13916ed 100644 --- a/docs/3.0/actions.md +++ b/docs/3.0/actions.md @@ -236,7 +236,7 @@ class Avo::Actions::DownloadFile < Avo::BaseAction end ``` -```ruby{5} [app/avo/resources/project_resource.rb] +```ruby{7} [app/avo/resources/project.rb] class Avo::Resources::Project < Avo::BaseResource def fields # fields here diff --git a/docs/3.0/associations.md b/docs/3.0/associations.md index 9dc9d051..4aa06569 100644 --- a/docs/3.0/associations.md +++ b/docs/3.0/associations.md @@ -28,16 +28,18 @@ end # User.all.map(&:class) => [User, SuperUser] ``` -For example, when you have two models, `User` and `SuperUser` with STI, when you call `User.all`, Rails will return an instance of `User` and an instance of `SuperUser`. That confuses Avo in producing the proper resource of `User`. That's why when you deal with STI, the final resource `SuperUserResource` should receive the underlying `model_class` so Avo knows which model it represents. +For example, when you have two models, `User` and `SuperUser` with STI, when you call `User.all`, Rails will return an instance of `User` and an instance of `SuperUser`. That confuses Avo in producing the proper resource of `User`. That's why when you deal with STI, the final resource `Avo::Resources::SuperUser` should receive the underlying `model_class` so Avo knows which model it represents. ```ruby{4} -class SuperUserResource < Avo::BaseResource +class Avo::Resources::SuperUser < Avo::BaseResource self.title = :name self.includes = [] self.model_class = ::SuperUser - field :id, as: :id - field :name, as: :text + def fields + field :id, as: :id + field :name, as: :text + end end ``` @@ -45,12 +47,12 @@ end Let's take another example. We have a `Person` model and `Sibling` and `Spouse` models that inherit from it. -You may want to use the `PersonResource` to list all the records, but when your user clicks on a person, you want to use the inherited resources (`SiblingResource` and `SpouseResource`) to display the details. The reason is that you may want to display different fields or resource tools for each resource type. +You may want to use the `Avo::Resources::Person` to list all the records, but when your user clicks on a person, you want to use the inherited resources (`Avo::Resources::Sibiling` and `Avo::Resources::Spouse`) to display the details. The reason is that you may want to display different fields or resource tools for each resource type. There are two ways you can use this: -1. `self.link_to_child_resource = true` Declare this option on the parent resource. When a user is on the view of your the `PersonResource` and clicks on the view button of a `Person` they will be redirected to a `Child` or `Spouse` resource instead of a `Person` resource. -2. `field :peoples, as: :has_many, link_to_child_resource: false` Use it on a `has_many` field. On the `PersonResource` you may want to show all the related people on the page, but when someone click on a record, they are redirected to the inherited `Child` or `Spouse` resource. +1. `self.link_to_child_resource = true` Declare this option on the parent resource. When a user is on the view of your the `Avo::Resources::Person` and clicks on the view button of a `Person` they will be redirected to a `Child` or `Spouse` resource instead of a `Person` resource. +2. `field :peoples, as: :has_many, link_to_child_resource: false` Use it on a `has_many` field. On the `Avo::Resources::Person` you may want to show all the related people on the page, but when someone click on a record, they are redirected to the inherited `Child` or `Spouse` resource. ## Add custom labels to the associations' pages diff --git a/docs/3.0/custom-fields.md b/docs/3.0/custom-fields.md index c657f9b2..118d14a8 100644 --- a/docs/3.0/custom-fields.md +++ b/docs/3.0/custom-fields.md @@ -34,7 +34,7 @@ Please restart your rails server after adding a new custom field. The `ProgressBarField` file is what registers the field in your admin. ```ruby -class ProgressBarField < Avo::Fields::BaseField +class Avo::Fields::ProgressBarField < Avo::Fields::BaseField def initialize(name, **args, &block) super(name, **args, &block) end @@ -43,13 +43,15 @@ end Now you can use your field like so: -```ruby{6} -# app/avo/resources/progress_bar_field.rb -class ProjectResource < Avo::BaseResource +```ruby{7} +# app/avo/resources/project.rb +class Avo::Resources::Project < Avo::BaseResource self.title = :name - field :id, as: :id, link_to_resource: true - field :progress, as: :progress_bar + def fields + field :id, as: :id, link_to_resource: true + field :progress, as: :progress_bar + end end ``` Progress custom field @@ -84,7 +86,7 @@ This file is where you may add field-specific options. ```ruby{3-6,11-14} # app/avo/fields/progress_bar_field.rb -class ProgressBarField < Avo::Fields::BaseField +class Avo::Fields::ProgressBarField < Avo::Fields::BaseField attr_reader :max attr_reader :step attr_reader :display_value @@ -103,9 +105,9 @@ end The field-specific options can come from the field declaration as well. -```ruby{11-14,23} +```ruby{11-14,24} # app/avo/fields/progress_bar_field.rb -class ProgressBarField < Avo::Fields::BaseField +class Avo::Fields::ProgressBarField < Avo::Fields::BaseField attr_reader :max attr_reader :step attr_reader :display_value @@ -121,12 +123,14 @@ class ProgressBarField < Avo::Fields::BaseField end end -# app/avo/resources/progress_bar_field.rb -class ProjectResource < Avo::BaseResource +# app/avo/resources/project.rb +class Avo::Resources::Project < Avo::BaseResource self.title = :name - field :id, as: :id, link_to_resource: true - field :progress, as: :progress_bar, step: 10, display_value: true, value_suffix: "%" + def fields + field :id, as: :id, link_to_resource: true + field :progress, as: :progress_bar, step: 10, display_value: true, value_suffix: "%" + end end ``` @@ -136,7 +140,7 @@ If you need to hide the field in some view, you can use the [visibility helpers] ```ruby{16} # app/avo/fields/progress_bar_field.rb -class ProgressBarField < Avo::Fields::BaseField +class Avo::Fields::ProgressBarField < Avo::Fields::BaseField attr_reader :max attr_reader :step attr_reader :display_value @@ -269,7 +273,7 @@ You should add the `:always_show` `attr_reader` and `@always_show` instance vari ```ruby{3,8} # app/avo/fields/color_picker_field.rb -class ColorPickerField < Avo::Fields::BaseField +class Avo::Fields::ColorPickerField < Avo::Fields::BaseField attr_reader :always_show def initialize(id, **args, &block) diff --git a/docs/3.0/customization.md b/docs/3.0/customization.md index d75676fb..cfb89651 100644 --- a/docs/3.0/customization.md +++ b/docs/3.0/customization.md @@ -415,8 +415,8 @@ end #### Using the `friendly` gem ::: code-group -```ruby [app/avo/resources/user_resource.rb] -class UserResource < Avo::BaseResource +```ruby [app/avo/resources/user.rb] +class Avo::Resources::User < Avo::BaseResource self.find_record_method = -> { # We have to add .friendly to the query query.friendly.find! id diff --git a/docs/3.0/field-options.md b/docs/3.0/field-options.md index a0089a10..ec64a64a 100644 --- a/docs/3.0/field-options.md +++ b/docs/3.0/field-options.md @@ -131,7 +131,7 @@ You can do that using this query. ::: code-group -```ruby{5} [app/avo/resources/post_resource.rb] +```ruby{5} [app/avo/resources/post.rb] class Avo::Resources::Post < Avo::BaseResource field :last_commented_at, as: :date, diff --git a/docs/3.0/localization.md b/docs/3.0/localization.md index 7b433416..03750796 100644 --- a/docs/3.0/localization.md +++ b/docs/3.0/localization.md @@ -11,8 +11,8 @@ Avo leverages Rails' powerful I18n translations module. When you run `bin/rails Let's say you want to localize a resource. All you need to do is add a `self.translation_key` class attribute in the `Resource` file. That will tell Avo to use that translation key to localize this resource. That will change the labels of that resource everywhere in Avo. ```ruby{4} -# app/avo/resources/user_resource.rb -class UserResource < Avo::BaseResource +# app/avo/resources/user.rb +class Avo::Resources::User < Avo::BaseResource self.title = :name self.translation_key = 'avo.resource_translations.user' end @@ -36,14 +36,16 @@ es: Similarly, you can even localize fields. All you need to do is add a `translation_key:` option on the field declaration. -```ruby{7} -# app/avo/resources/project_resource.rb -class ProjectResource < Avo::BaseResource +```ruby{8} +# app/avo/resources/project.rb +class Avo::Resources::Project < Avo::BaseResource self.title = :name - field :id, as: :id - # ... other fields - field :files, as: :files, translation_key: 'avo.field_translations.file' + def fields + field :id, as: :id + # ... other fields + field :files, as: :files, translation_key: 'avo.field_translations.file' + end end ``` diff --git a/docs/3.0/menu-editor.md b/docs/3.0/menu-editor.md index 95427ecf..584ca639 100644 --- a/docs/3.0/menu-editor.md +++ b/docs/3.0/menu-editor.md @@ -104,11 +104,11 @@ When you add the `target: :_blank` option, a tiny external link icon will be dis :::option `resource` -To make it a bit easier, you can use `resource` to quickly generate a link to one of your resources. For example, you can pass a short symbol name `:user` or the full name `UserResource`. +To make it a bit easier, you can use `resource` to quickly generate a link to one of your resources. For example, you can pass a short symbol name `:user` or the full name `Avo::Resources::User`. ```ruby resource :posts -resource "CommentsResource" +resource "Avo::Resources::Comments" ``` Avo menu editor @@ -282,7 +282,6 @@ Avo.configure do |config| end ``` -::: ## Icons diff --git a/docs/3.0/resource-tools.md b/docs/3.0/resource-tools.md index 33ac978a..cd5e448c 100644 --- a/docs/3.0/resource-tools.md +++ b/docs/3.0/resource-tools.md @@ -15,7 +15,7 @@ Run `bin/rails generate avo:resource_tool post_info`. That will create two files The configuration file holds the tool's name and the partial path if you want to override it. ```ruby -class PostInfo < Avo::BaseResourceTool +class Avo::ResourceTools::PostInfo < Avo::BaseResourceTool self.name = "Post info" # self.partial = "avo/resource_tools/post_info" end @@ -76,9 +76,11 @@ That should give you all the necessary data to scope out the partial content. The resource tool is default visible on the `Show` view of a resource. You can change that using the [visibility options](field-options.html#showing-hiding-fields-on-different-views) (`show_on`, `only_on`). ```ruby -# app/avo/resources/post_resource.rb -class PostResource < Avo::BaseResource - tool PostInfo, show_on: :edit +# app/avo/resources/post.rb +class Avo::Resources::Post < Avo::BaseResource + def fields + tool Avo::ResourceTools::PostInfo, show_on: :edit + end end ``` @@ -108,13 +110,15 @@ You have to follow three steps to enable this functionality: 2. Tell Avo which `params` it should permit to write to the model 3. Make sure the model is equipped to receive the params -In the example below, we'll use the `FishResource`, add a few input fields (they will be a bit unstyled because this is not the scope of the exercise), and do some actions with some of them. +In the example below, we'll use the `Avo::Resources::Fish`, add a few input fields (they will be a bit unstyled because this is not the scope of the exercise), and do some actions with some of them. We first need to generate the tool with `bin/rails g avo:resource_tool fish_information` and add the tool to the resource file. -```ruby{2} -class FishResource < Avo::BaseResource - tool FishInformation, show_on: :forms +```ruby{3} +class Avo::ResourcesFish < Avo::BaseResource + def fields + tool Avo::ResourceTools::FishInformation, show_on: :forms + end end ``` @@ -170,13 +174,15 @@ The fields are: ``` -Next, we need to tell Avo and Rails which params are welcomed in the `create`/`update` request. We do that using the `extra_params` option on the `FishResource`. Avo's internal implementation is to assign the attributes you specify here to the underlying model (`model.assign_attributes params.permit(extra_params)`). +Next, we need to tell Avo and Rails which params are welcomed in the `create`/`update` request. We do that using the `extra_params` option on the `Avo::Resources::Fish`. Avo's internal implementation is to assign the attributes you specify here to the underlying model (`model.assign_attributes params.permit(extra_params)`). ```ruby{2} -class FishResource < Avo::BaseResource +class Avo::Resources::Fish < Avo::BaseResource self.extra_params = [:fish_type, :something_else, properties: [], information: [:name, :history]] - tool FishInformation, show_on: :forms + def fields + tool Avo::ResourceTools::FishInformation, show_on: :forms + end end ``` diff --git a/docs/3.0/resources.md b/docs/3.0/resources.md index 2797d90e..a58242d0 100644 --- a/docs/3.0/resources.md +++ b/docs/3.0/resources.md @@ -260,7 +260,7 @@ class Avo::Resources::Team < Avo::BaseResource def fields field :id, as: :id, link_to_resource: true field :name, as: :text - field :users, as: :has_many, use_resource: TeamUserResource + field :users, as: :has_many, use_resource: Avo::Resources::TeamUser end end ``` @@ -276,7 +276,7 @@ To mitigate that, we are going to use the `model_resource_mapping` option to set # config/initializers/avo.rb Avo.configure do |config| config.model_resource_mapping = { - 'User': 'UserResource' + 'User': 'Avo::Resources::User' } end ``` @@ -363,8 +363,8 @@ If you want to manually load them use the `config.resources` option. # config/initializers/avo.rb Avo.configure do |config| config.resources = [ - "UserResource", - "FishResource", + "Avo::Resources::User", + "Avo::Resources::Fish", ] end ``` diff --git a/docs/3.0/stimulus-integration.md b/docs/3.0/stimulus-integration.md index be249223..49abe210 100644 --- a/docs/3.0/stimulus-integration.md +++ b/docs/3.0/stimulus-integration.md @@ -32,7 +32,7 @@ You'll be able to add your Stimulus controllers to the resource views (`Index`, To enable a stimulus controller to resource view, you can use the `stimulus_controllers` option on the resource file. ```ruby -class CourseResource < Avo::BaseResource +class Avo::Resources::Course < Avo::BaseResource self.stimulus_controllers = "course-resource" end ``` @@ -40,7 +40,7 @@ end You can add more and separate them by a space character. ```ruby -class CourseResource < Avo::BaseResource +class Avo::Resources::Course < Avo::BaseResource self.stimulus_controllers = "course-resource select-field association-fields" end ``` @@ -444,32 +444,34 @@ Below is an example of how you could implement a city & country select feature w ::: code-group -```ruby [app/avo/resources/course_resource.rb] -# app/avo/resources/course_resource.rb -class CourseResource < Avo::BaseResource +```ruby [app/avo/resources/course.rb] +# app/avo/resources/course.rb +class Avo::Resources::Course < Avo::BaseResource self.stimulus_controllers = "course-resource" - field :id, as: :id - field :name, as: :text - field :country, as: :select, options: Course.countries.map { |country| [country, country] }.to_h, html: { - edit: { - input: { - data: { - course_resource_target: "countryFieldInput", # Make the input a target - action: "input->course-resource#onCountryChange" # Add an action on change + def fields + field :id, as: :id + field :name, as: :text + field :country, as: :select, options: Course.countries.map { |country| [country, country] }.to_h, html: { + edit: { + input: { + data: { + course_resource_target: "countryFieldInput", # Make the input a target + action: "input->course-resource#onCountryChange" # Add an action on change + } } } } - } - field :city, as: :select, options: Course.cities.values.flatten.map { |city| [city, city] }.to_h, html: { - edit: { - input: { - data: { - course_resource_target: "cityFieldInput" # Make the input a target + field :city, as: :select, options: Course.cities.values.flatten.map { |city| [city, city] }.to_h, html: { + edit: { + input: { + data: { + course_resource_target: "cityFieldInput" # Make the input a target + } } } } - } + end end ``` From b88747c08703378e8ca5b99392cf47be26051bfc Mon Sep 17 00:00:00 2001 From: Paul Bob Date: Mon, 7 Aug 2023 18:44:58 +0300 Subject: [PATCH 2/3] more updates --- docs/.vitepress/config.js | 36 ++++++++++++++++++------------------ docs/3.0/testing.md | 16 +++++++++------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index ae557f67..8db96e7c 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -110,8 +110,8 @@ const config = { text: "Configuration", items: [ {text: "Installation", link: "/3.0/installation"}, - // {text: "Authentication", link: "/3.0/authentication"}, - // {text: "Authorization", link: "/3.0/authorization"}, + {text: "Authentication", link: "/3.0/authentication"}, + {text: "Authorization", link: "/3.0/authorization"}, ], }, { @@ -188,22 +188,22 @@ const config = { {text: "Custom asset pipeline", link: "/3.0/custom-asset-pipeline"}, ], }, - // { - // text: "Native Avo components", - // items: [ - // {text: "Avo::PanelComponent", link: "/3.0/native-components/avo-panel-component"}, - // {text: "Native field components", link: "/3.0/native-field-components"}, - // {text: "Field wrappers", link: "/3.0/field-wrappers"}, - // ], - // }, - // { - // text: "Internals", - // items: [ - // {text: "Testing", link: "/3.0/testing"}, - // {text: "Avo::ApplicationController", link: "/3.0/avo-application-controller"}, - // {text: "Avo.asset_manager", link: "/3.0/asset-manager"}, - // ], - // }, + { + text: "Native Avo components", + items: [ + {text: "Avo::PanelComponent", link: "/3.0/native-components/avo-panel-component"}, + {text: "Native field components", link: "/3.0/native-field-components"}, + {text: "Field wrappers", link: "/3.0/field-wrappers"}, + ], + }, + { + text: "Internals", + items: [ + {text: "Testing", link: "/3.0/testing"}, + {text: "Avo::ApplicationController", link: "/3.0/avo-application-controller"}, + {text: "Avo.asset_manager", link: "/3.0/asset-manager"}, + ], + }, // { // text: "Extending", // items: [ diff --git a/docs/3.0/testing.md b/docs/3.0/testing.md index a927435e..b33b910a 100644 --- a/docs/3.0/testing.md +++ b/docs/3.0/testing.md @@ -18,21 +18,23 @@ You can find them all [here](https://github.com/avo-hq/avo-3/blob/main/lib/avo/t ## Testing Actions -Given this `ReleaseFish`, this is the `spec` that tests it. +Given this `Avo::Actions::ReleaseFish`, this is the `spec` that tests it. ```ruby -class ReleaseFish < Avo::BaseAction +class Avo::Actions::ReleaseFish < Avo::BaseAction self.name = "Release fish" self.message = "Are you sure you want to release this fish?" - field :message, as: :textarea, help: "Tell the fish something before releasing." + def fields + field :message, as: :textarea, help: "Tell the fish something before releasing." + end def handle(**args) - args[:models].each do |model| - model.release + args[:records].each do |record| + record.release end - succeed "#{args[:models].count} fish released with message '#{args[:fields][:message]}'." + succeed "#{args[:records].count} fish released with message '#{args[:fields][:message]}'." end end @@ -44,7 +46,7 @@ require 'rails_helper' RSpec.feature ReleaseFish, type: :feature do let(:fish) { create :fish } let(:current_user) { create :user } - let(:resource) { UserResource.new.hydrate model: fish } + let(:resource) { Avo::Resources::User.new.hydrate model: fish } it "tests the dummy action" do args = { From 1ac779eefe1adef0c348e13f189904f7eaefeee1 Mon Sep 17 00:00:00 2001 From: Paul Bob Date: Mon, 7 Aug 2023 18:50:03 +0300 Subject: [PATCH 3/3] final updates --- docs/3.0/authorization.md | 4 +- docs/3.0/faq.md | 76 +++++++++++-------- .../recipes/nested-records-when-creating.md | 21 ++--- .../use-own-helpers-in-resource-files.md | 8 +- 4 files changed, 62 insertions(+), 47 deletions(-) diff --git a/docs/3.0/authorization.md b/docs/3.0/authorization.md index 360b7e0f..2721d7b6 100644 --- a/docs/3.0/authorization.md +++ b/docs/3.0/authorization.md @@ -412,7 +412,7 @@ Now, Avo will use `avo_index?` instead of `index?` to manage the **Index** view ## Raise errors when policies are missing -The default behavior of Avo is to allow missing policies for resources silently. So, if you have a `User` model and a `UserResource` but don't have a `UserPolicy`, Avo will not raise errors regarding missing policies and authorize that resource. +The default behavior of Avo is to allow missing policies for resources silently. So, if you have a `User` model and a `Avo::Resources::User` but don't have a `UserPolicy`, Avo will not raise errors regarding missing policies and authorize that resource. If, however, you need to be on the safe side of things and raise errors when a Resource is missing a Policy, you can toggle on the `raise_error_on_missing_policy` configuration. @@ -436,7 +436,7 @@ Now, you'll have to provide a policy for each resource you have in your app, thu By default, Avo will infer the policy from the model of the resource object. If you wish to use a different policy for a given resource, you can specify it directly in the resource using the `authorization_policy` option. ```ruby -class PhotoCommentResource < Avo::BaseResource +class Avo::Resources::PhotoComment < Avo::BaseResource self.model_class = ::Comment self.authorization_policy = PhotoCommentPolicy # ... diff --git a/docs/3.0/faq.md b/docs/3.0/faq.md index 3b1704c7..2dc3fe0d 100644 --- a/docs/3.0/faq.md +++ b/docs/3.0/faq.md @@ -68,7 +68,7 @@ That depends on your setup: 1. If you have [Rails STI](https://guides.rubyonrails.org/association_basics.html#single-table-inheritance-sti), then it will work. Avo knows how to handle STI models. So you'll have two models and an Avo resource for each one. That will render two resources in your admin panel's sidebar. 2. You don't have Rails STI but something custom. Then the response is it depends. Because something custom is... custom, we offer a few mechanisms to get over that. -If you have one model, `User`, you'll have one Avo resource, `UserResource`. +If you have one model, `User`, you'll have one Avo resource, `Avo::Resources::User`. Then you can customize different things based on your requirements. Like if for instance, you want to show only some types of users on the `Index` view, you can use [custom query scopes](https://docs.avohq.io/1.0/customization.html#custom-query-scopes) to hide specific types (if that's what you want to do). Same if you want to [show/hide fields](https://docs.avohq.io/1.0/field-options.html#field-visibility) based on the resource type or type of user. @@ -118,16 +118,18 @@ For convenience sake, we capture the `view_context` for you and set it to the `A On the `Resource` and `Field` classes, it's already delegated for you, so you can just use `view_context`. -```ruby{6,9} -class CommentResource < Avo::BaseResource - field :id, as: :id - field :body, - as: :textarea, - format_using: -> do - view_context.content_tag(:div, style: 'white-space: pre-line') { value } +```ruby{7,10} +class Avo::Resources::Comment < Avo::BaseResource + def fields + field :id, as: :id + field :body, + as: :textarea, + format_using: -> do + view_context.content_tag(:div, style: 'white-space: pre-line') { value } + end + field :computed_field, as: :text do + view_context.link_to("Login", main_app.new_user_session_path) end - field :computed_field, as: :text do - view_context.link_to("Login", main_app.new_user_session_path) end end ``` @@ -138,9 +140,11 @@ end When adding content using the `textarea` field, you might see that the newlines are not displayed on the `Show` view. -```ruby{2} -class CommentResource < Avo::BaseResource - field :body, as: :textarea +```ruby{3} +class Avo::Resources::Comment < Avo::BaseResource + def fields + field :body, as: :textarea + end end ``` @@ -151,13 +155,15 @@ You can change how you display the information by using the `format_using` optio ### Use `simple_format` -```ruby{5} -class CommentResource < Avo::BaseResource - field :body, - as: :textarea, - format_using: -> do - simple_format value - end +```ruby{6} +class Avo::Resources::Comment < Avo::BaseResource + def fields + field :body, + as: :textarea, + format_using: -> do + simple_format value + end + end end ``` @@ -165,12 +171,14 @@ end ### Use the `white-space: pre-line` style rule -```ruby{5} -class CommentResource < Avo::BaseResource - field :body, - as: :textarea, - format_using: -> do - content_tag(:div, style: 'white-space: pre-line') { value } +```ruby{6} +class Avo::Resources::Comment < Avo::BaseResource + def fields + field :body, + as: :textarea, + format_using: -> do + content_tag(:div, style: 'white-space: pre-line') { value } + end end end ``` @@ -179,13 +187,15 @@ end ### Use the `whitespace-pre-line` class -```ruby{5} -class CommentResource < Avo::BaseResource - field :body, - as: :textarea, - format_using: -> do - content_tag(:div, class: 'whitespace-pre-line') { value } - end +```ruby{6} +class Avo::Resources::Comment < Avo::BaseResource + def fields + field :body, + as: :textarea, + format_using: -> do + content_tag(:div, class: 'whitespace-pre-line') { value } + end + end end ``` diff --git a/docs/3.0/recipes/nested-records-when-creating.md b/docs/3.0/recipes/nested-records-when-creating.md index 5aef1bf8..f3a63b91 100644 --- a/docs/3.0/recipes/nested-records-when-creating.md +++ b/docs/3.0/recipes/nested-records-when-creating.md @@ -57,19 +57,21 @@ Use [this guide](./../custom-asset-pipeline.html#add-custom-js-code-and-stimulus `bin/rails generate avo:resource_tool nested_fish_reviews` -This will generate two files. The `NestedFishReviews` ruby file you'll register on the `FishResource` file and we'll edit the template to contain our fields. +This will generate two files. The `NestedFishReviews` ruby file you'll register on the `Avo::Resources::Fish` file and we'll edit the template to contain our fields. ### 4. Register the tool on the resource We'll display it only on the view. -```ruby{6} -class FishResource < Avo::BaseResource +```ruby{7} +class Avo::Resources::Fish < Avo::BaseResource # other fields actions, filters and more - field :reviews, as: :has_many + def fields + field :reviews, as: :has_many - tool NestedFishReviews, only_on: :new + tool Avo::ResourceTools::NestedFishReviews, only_on: :new + end end ``` @@ -131,14 +133,15 @@ In the footer we'll also add the button that will add new reviews on the page. There's one more step we need to do and that's to whitelist the new `reviews_attributes` params to be passed to the model. ```ruby{2} -class FishResource < Avo::BaseResource +class Avo::Resources::Fish < Avo::BaseResource self.extra_params = [reviews_attributes: [:body, :user_id]] # other fields actions, filters and more + def fields + field :reviews, as: :has_many - field :reviews, as: :has_many - - tool NestedFishReviews, only_on: :new + tool Avo::ResourceTools::NestedFishReviews, only_on: :new + end end ``` diff --git a/docs/3.0/recipes/use-own-helpers-in-resource-files.md b/docs/3.0/recipes/use-own-helpers-in-resource-files.md index dfb7ef34..9e6cb9cd 100644 --- a/docs/3.0/recipes/use-own-helpers-in-resource-files.md +++ b/docs/3.0/recipes/use-own-helpers-in-resource-files.md @@ -24,9 +24,11 @@ end Now, you'd like to use that helper inside one of you computed fields. ```ruby -class PostResource < Avo::BaseResource - field :excerpt, as: :text do |model| - extract_excerpt model.body +class Avo::Resources::Post < Avo::BaseResource + def fields + field :excerpt, as: :text do |model| + extract_excerpt model.body + end end end ```