avo 2.5.2.pre.2 → 2.5.2.pre.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +0 -2
- data/Gemfile.lock +1 -4
- data/app/assets/builds/avo.css +222 -812
- data/app/assets/builds/avo.js +123 -212
- data/app/assets/builds/avo.js.map +3 -3
- data/app/assets/stylesheets/avo.css +33 -3
- data/app/assets/stylesheets/css/search.css +1 -1
- data/app/assets/svgs/heroicons/solid/user-remove.svg +1 -1
- data/app/components/avo/actions_component.html.erb +2 -1
- data/app/components/avo/alert_component.html.erb +1 -1
- data/app/components/avo/alert_component.rb +24 -5
- data/app/components/avo/button_component.rb +2 -0
- data/app/components/avo/filters_component.html.erb +1 -1
- data/app/components/avo/index/field_wrapper_component.html.erb +1 -1
- data/app/components/avo/index/grid_cover_empty_state_component.html.erb +1 -1
- data/app/components/avo/index/resource_table_component.html.erb +1 -1
- data/app/components/avo/panel_component.html.erb +3 -3
- data/app/components/avo/panel_component.rb +1 -1
- data/app/components/avo/resource_component.rb +50 -0
- data/app/components/avo/sidebar/heading_component.html.erb +1 -1
- data/app/components/avo/sidebar/link_component.rb +1 -1
- data/app/components/avo/sidebar_component.html.erb +5 -13
- data/app/components/avo/sidebar_profile_component.html.erb +1 -1
- data/app/components/avo/views/resource_edit_component.html.erb +28 -3
- data/app/components/avo/views/resource_edit_component.rb +4 -6
- data/app/components/avo/views/resource_index_component.html.erb +15 -7
- data/app/components/avo/views/resource_new_component.html.erb +8 -2
- data/app/components/avo/views/resource_show_component.html.erb +15 -5
- data/app/components/avo/views/resource_show_component.rb +0 -45
- data/app/controllers/avo/actions_controller.rb +23 -8
- data/app/controllers/avo/associations_controller.rb +1 -1
- data/app/controllers/avo/base_controller.rb +25 -16
- data/app/helpers/avo/application_helper.rb +1 -1
- data/app/javascript/js/application.js +1 -1
- data/app/javascript/js/controllers/fields/key_value_controller.js +1 -1
- data/app/javascript/js/controllers/filter_controller.js +4 -1
- data/app/javascript/js/controllers.js +0 -4
- data/app/views/avo/actions/show.html.erb +5 -2
- data/app/views/avo/partials/_logo.html.erb +1 -1
- data/app/views/avo/partials/_navbar.html.erb +12 -6
- data/app/views/avo/private/_links_and_buttons.html.erb +1 -1
- data/app/views/layouts/avo/application.html.erb +47 -53
- data/db/factories.rb +0 -2
- data/lib/avo/base_action.rb +24 -6
- data/lib/avo/base_resource.rb +0 -6
- data/lib/avo/engine.rb +1 -1
- data/lib/avo/fields/base_field.rb +1 -2
- data/lib/avo/fields/has_and_belongs_to_many_field.rb +2 -2
- data/lib/avo/fields/has_many_field.rb +2 -2
- data/lib/avo/fields/has_one_field.rb +2 -2
- data/lib/avo/licensing/pro_license.rb +1 -2
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/locales/avo.en.yml +0 -4
- data/public/avo-assets/avo.css +214 -812
- data/public/avo-assets/avo.js +123 -212
- data/public/avo-assets/avo.js.map +3 -3
- metadata +2 -19
- data/app/assets/stylesheets/css/alerts.css +0 -35
- data/app/assets/stylesheets/css/tags.css +0 -16
- data/app/components/avo/fields/tags_field/edit_component.html.erb +0 -27
- data/app/components/avo/fields/tags_field/edit_component.rb +0 -4
- data/app/components/avo/fields/tags_field/index_component.html.erb +0 -14
- data/app/components/avo/fields/tags_field/index_component.rb +0 -7
- data/app/components/avo/fields/tags_field/show_component.html.erb +0 -7
- data/app/components/avo/fields/tags_field/show_component.rb +0 -11
- data/app/components/avo/fields/tags_field/tag_component.html.erb +0 -9
- data/app/components/avo/fields/tags_field/tag_component.rb +0 -11
- data/app/javascript/js/controllers/alerts_controller.js +0 -26
- data/app/javascript/js/controllers/base_controller.js +0 -22
- data/app/javascript/js/controllers/fields/tags_field_controller.js +0 -86
- data/app/javascript/js/controllers/fields/tags_field_helpers.js +0 -47
- data/lib/avo/concerns/handles_field_args.rb +0 -36
- data/lib/avo/fields/tags_field.rb +0 -82
- data/lib/avo/hosts/record_host.rb +0 -7
@@ -11,8 +11,8 @@ module Avo
|
|
11
11
|
before_action :set_edit_title_and_breadcrumbs, only: [:edit, :update]
|
12
12
|
before_action :fill_model, only: [:create, :update]
|
13
13
|
before_action :authorize_action
|
14
|
-
before_action :reset_pagination_if_filters_changed, only: :index
|
15
|
-
before_action :cache_applied_filters, only: :index
|
14
|
+
# before_action :reset_pagination_if_filters_changed, only: :index
|
15
|
+
# before_action :cache_applied_filters, only: :index
|
16
16
|
|
17
17
|
def index
|
18
18
|
@page_title = @resource.plural_name.humanize
|
@@ -49,10 +49,10 @@ module Avo
|
|
49
49
|
# Check if the sortable field option is actually a proc and we need to do a custom sort
|
50
50
|
field_id = @index_params[:sort_by].to_sym
|
51
51
|
field = @resource.get_field_definitions.find { |field| field.id == field_id }
|
52
|
-
if field&.sortable.is_a?(Proc)
|
53
|
-
|
52
|
+
@query = if field&.sortable.is_a?(Proc)
|
53
|
+
field.sortable.call(@query, @index_params[:sort_direction])
|
54
54
|
else
|
55
|
-
@query
|
55
|
+
@query.order("#{@resource.model_class.table_name}.#{@index_params[:sort_by]} #{@index_params[:sort_direction]}")
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -61,7 +61,14 @@ module Avo
|
|
61
61
|
@query = filter_class.safe_constantize.new.apply_query request, @query, filter_value
|
62
62
|
end
|
63
63
|
|
64
|
-
|
64
|
+
extra_pagy_params = {}
|
65
|
+
|
66
|
+
# Reset open filters when a user navigates to a new page
|
67
|
+
extra_pagy_params[:keep_filters_panel_open] = if params[:keep_filters_panel_open] == "1"
|
68
|
+
"0"
|
69
|
+
end
|
70
|
+
|
71
|
+
@pagy, @models = pagy(@query, items: @index_params[:per_page], link_extra: "data-turbo-frame=\"#{params[:turbo_frame]}\"", size: [1, 2, 2, 1], params: extra_pagy_params)
|
65
72
|
|
66
73
|
# Create resources for each model
|
67
74
|
@resources = @models.map do |model|
|
@@ -354,19 +361,21 @@ module Avo
|
|
354
361
|
end
|
355
362
|
|
356
363
|
# Caching these so we know when the filters have changed so we reset the pagination
|
357
|
-
def cache_applied_filters
|
358
|
-
|
364
|
+
# def cache_applied_filters
|
365
|
+
# # puts ["Rails.session->", session].inspect
|
366
|
+
# session[:avo_applied_filters] = params[:filters]
|
367
|
+
# # ::Avo::App.cache_store.delete(applied_filters_cache_key) if params[:filters].nil?
|
359
368
|
|
360
|
-
|
361
|
-
end
|
369
|
+
# # ::Avo::App.cache_store.write(applied_filters_cache_key, params[:filters], expires_in: 1.day)
|
370
|
+
# end
|
362
371
|
|
363
|
-
def reset_pagination_if_filters_changed
|
364
|
-
|
365
|
-
end
|
372
|
+
# def reset_pagination_if_filters_changed
|
373
|
+
# params[:page] = 1 if params[:filters] != session[:avo_applied_filters]
|
374
|
+
# end
|
366
375
|
|
367
|
-
def applied_filters_cache_key
|
368
|
-
|
369
|
-
end
|
376
|
+
# def applied_filters_cache_key
|
377
|
+
# "avo.base_controller.#{@resource.model_key}.applied_filters"
|
378
|
+
# end
|
370
379
|
|
371
380
|
def set_edit_title_and_breadcrumbs
|
372
381
|
@resource = @resource.hydrate(model: @model, view: :edit, user: _current_user)
|
@@ -118,7 +118,7 @@ module Avo
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def input_classes(extra_classes = "", has_error: false)
|
121
|
-
classes = "appearance-none inline-flex bg-gray-
|
121
|
+
classes = "appearance-none inline-flex bg-gray-25 disabled:cursor-not-allowed text-gray-600 disabled:opacity-50 rounded py-2 px-3 leading-tight border focus:border-gray-600 focus-visible:ring-0 focus:text-gray-700"
|
122
122
|
|
123
123
|
classes += if has_error
|
124
124
|
" border-red-600"
|
@@ -4,7 +4,7 @@ import { Application } from '@hotwired/stimulus'
|
|
4
4
|
const application = Application.start()
|
5
5
|
|
6
6
|
// Configure Stimulus development experience
|
7
|
-
application.debug =
|
7
|
+
application.debug = false
|
8
8
|
window.Stimulus = application
|
9
9
|
|
10
10
|
// Register stimulus-components controller
|
@@ -110,7 +110,7 @@ export default class extends Controller {
|
|
110
110
|
|
111
111
|
inputField(id = 'key', index, key, value) {
|
112
112
|
return `<input
|
113
|
-
class="${this.options.inputClasses} !rounded-none border-gray-600 border-r border-l-0 border-b-0 border-t-0 focus:border-gray-300 w-1/2 focus:outline-none outline-none key-value-input-${id}"
|
113
|
+
class="${this.options.inputClasses} focus:bg-gray-100 !rounded-none border-gray-600 border-r border-l-0 border-b-0 border-t-0 focus:border-gray-300 w-1/2 focus:outline-none outline-none key-value-input-${id}"
|
114
114
|
data-action="input->key-value#${id}FieldUpdated"
|
115
115
|
placeholder="${this.options[`${id}_label`]}"
|
116
116
|
data-index="${index}"
|
@@ -84,9 +84,12 @@ export default class extends Controller {
|
|
84
84
|
|
85
85
|
if (this.keepFiltersPanelOpenValue) {
|
86
86
|
// eslint-disable-next-line camelcase
|
87
|
-
query.keep_filters_panel_open = this.keepFiltersPanelOpenValue
|
87
|
+
query.keep_filters_panel_open = this.keepFiltersPanelOpenValue ? 1 : null
|
88
88
|
}
|
89
89
|
|
90
|
+
// force to go to the first page if the filters changed
|
91
|
+
query.page = 1
|
92
|
+
|
90
93
|
if (encodedFilters) {
|
91
94
|
query.filters = encodedFilters
|
92
95
|
} else {
|
@@ -2,7 +2,6 @@ import { application } from './application'
|
|
2
2
|
|
3
3
|
import ActionController from './controllers/action_controller'
|
4
4
|
import ActionsPickerController from './controllers/actions_picker_controller'
|
5
|
-
import AlertsController from './controllers/alerts_controller'
|
6
5
|
import AttachmentsController from './controllers/attachments_controller'
|
7
6
|
import BelongsToFieldController from './controllers/fields/belongs_to_field_controller'
|
8
7
|
import BooleanFilterController from './controllers/boolean_filter_controller'
|
@@ -25,7 +24,6 @@ import SearchController from './controllers/search_controller'
|
|
25
24
|
import SelectController from './controllers/select_controller'
|
26
25
|
import SelectFilterController from './controllers/select_filter_controller'
|
27
26
|
import SimpleMdeController from './controllers/fields/simple_mde_controller'
|
28
|
-
import TagsFieldController from './controllers/fields/tags_field_controller'
|
29
27
|
import TextFilterController from './controllers/text_filter_controller'
|
30
28
|
import TippyController from './controllers/tippy_controller'
|
31
29
|
import TogglePanelController from './controllers/toggle_panel_controller'
|
@@ -33,7 +31,6 @@ import TrixFieldController from './controllers/fields/trix_field_controller'
|
|
33
31
|
|
34
32
|
application.register('action', ActionController)
|
35
33
|
application.register('actions-picker', ActionsPickerController)
|
36
|
-
application.register('alerts', AlertsController)
|
37
34
|
application.register('attachments', AttachmentsController)
|
38
35
|
application.register('boolean-filter', BooleanFilterController)
|
39
36
|
application.register('copy-to-clipboard', CopyToClipboardController)
|
@@ -51,7 +48,6 @@ application.register('per-page', PerPageController)
|
|
51
48
|
application.register('search', SearchController)
|
52
49
|
application.register('select', SelectController)
|
53
50
|
application.register('select-filter', SelectFilterController)
|
54
|
-
application.register('tags-field', TagsFieldController)
|
55
51
|
application.register('text-filter', TextFilterController)
|
56
52
|
application.register('tippy', TippyController)
|
57
53
|
application.register('toggle-panel', TogglePanelController)
|
@@ -29,11 +29,14 @@
|
|
29
29
|
</div>
|
30
30
|
<% end %>
|
31
31
|
<% c.controls do %>
|
32
|
-
<%= a_button data: { action: 'click->modal#close' },
|
32
|
+
<%= a_button data: { action: 'click->modal#close' },
|
33
|
+
size: :sm,
|
34
|
+
color: :primary do %>
|
33
35
|
<%= @action.cancel_button_label %>
|
34
36
|
<% end %>
|
35
37
|
<%= a_button type: :submit,
|
36
|
-
color: :
|
38
|
+
color: :primary,
|
39
|
+
style: :primary,
|
37
40
|
size: :sm,
|
38
41
|
data: @action.class.submit_button_data_attributes do %>
|
39
42
|
<%= @action.confirm_button_label %>
|
@@ -1,14 +1,20 @@
|
|
1
1
|
<div
|
2
|
-
class="
|
2
|
+
class="fixed bg-white p-2 w-full flex flex-shrink-0 items-center z-50 px-4 lg:px-4 border-b space-x-4 lg:space-x-0 min-h-[4rem] <%= 'print:hidden' if Avo.configuration.hide_layout_when_printing %>"
|
3
3
|
v-if="layout !== 'blank'"
|
4
4
|
>
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
<div class="flex items-center space-x-2 lg:space-x-0 w-64">
|
6
|
+
<%= a_button class: 'lg:hidden', icon: 'menu', size: :xs, compact: true, style: :text, data: { action: 'click->mobile#toggleSidebar' } %>
|
7
|
+
|
8
|
+
<%= render partial: "avo/partials/logo" %>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
|
12
|
+
<div class="flex-1 flex items-center justify-between lg:justify-start space-x-8 pl-4">
|
10
13
|
<div class="flex">
|
11
14
|
<%= render partial: "avo/partials/global_search" if ::Avo::App.license.has_with_trial(:global_search) && ::Avo.configuration.feature_enabled?(:global_search) %>
|
12
15
|
</div>
|
16
|
+
<div class="m-0">
|
17
|
+
<%= render partial: "avo/partials/header" %>
|
18
|
+
</div>
|
13
19
|
</div>
|
14
20
|
</div>
|
@@ -1,60 +1,54 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
|
-
<head>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
<% if Rails.env.development? %>
|
20
|
-
<%= javascript_include_tag "hotwire-livereload", defer: true %>
|
3
|
+
<head>
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
5
|
+
<%= display_meta_tags site: Avo.configuration.app_name, reverse: true, separator: "—" %>
|
6
|
+
<%= csrf_meta_tags %>
|
7
|
+
<%= csp_meta_tag %>
|
8
|
+
<%= render partial: 'avo/partials/javascript' %>
|
9
|
+
<%= render partial: 'avo/partials/head' %>
|
10
|
+
<% if Avo::PACKED %>
|
11
|
+
<%= javascript_include_tag "/avo-assets/avo", "data-turbo-track": "reload", defer: true %>
|
12
|
+
<%= stylesheet_link_tag "/avo-assets/avo", "data-turbo-track": "reload", defer: true %>
|
13
|
+
<% else %>
|
14
|
+
<%= javascript_include_tag "avo", "data-turbo-track": "reload", defer: true %>
|
15
|
+
<%= stylesheet_link_tag "avo", "data-turbo-track": "reload", defer: true %>
|
16
|
+
<% if Rails.env.development? %>
|
17
|
+
<%= javascript_include_tag "hotwire-livereload", defer: true %>
|
18
|
+
<% end %>
|
21
19
|
<% end %>
|
22
|
-
|
23
|
-
|
24
|
-
<
|
25
|
-
<div class="
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
20
|
+
</head>
|
21
|
+
<body class="bg-gray-25 os-mac">
|
22
|
+
<div class="relative flex flex-1 w-full min-h-full" data-controller="mobile">
|
23
|
+
<div class="flex-1 flex flex-col max-w-full">
|
24
|
+
<%= render partial: "avo/partials/navbar" %>
|
25
|
+
<div class="flex-1 flex pt-16 relative">
|
26
|
+
<%= render Avo::SidebarComponent.new %>
|
27
|
+
<div class="lg:pl-64 flex-1 flex flex-col min-h-full max-w-full">
|
28
|
+
<div class="content py-4 lg:py-8 px-4 lg:px-8 flex-1 flex flex-col justify-between items-stretch <%= @container_classes %>">
|
29
|
+
<%= render partial: "avo/partials/custom_tools_alert" if @custom_tools_alert_visible %>
|
30
|
+
<div class="flex flex-1 flex-col justify-between items-stretch space-y-8">
|
31
|
+
<%= yield %>
|
32
|
+
<%= render partial: "avo/partials/footer" %>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
37
|
</div>
|
38
38
|
</div>
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
<%= turbo_frame_tag '
|
43
|
-
<%=
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
<% if @errors.present? %>
|
51
|
-
<% @errors.each do |message| %>
|
52
|
-
<%= render Avo::AlertComponent.new :error, message %>
|
39
|
+
<%= turbo_frame_tag 'actions_show' %>
|
40
|
+
<%= turbo_frame_tag 'attach_modal' %>
|
41
|
+
<%= turbo_frame_tag 'destroy_attachment_form' %>
|
42
|
+
<%= turbo_frame_tag 'alerts', class: "fixed inset-0 bottom-0 flex flex-col space-y-4 items-end justify-right px-4 py-6 sm:p-6 justify-end z-50 pointer-events-none" do %>
|
43
|
+
<%= render Avo::FlashAlertsComponent.new flashes: flash %>
|
44
|
+
<% # In case we have other general error messages %>
|
45
|
+
<% if @errors.present? %>
|
46
|
+
<% @errors.each do |message| %>
|
47
|
+
<%= render Avo::AlertComponent.new :error, message %>
|
48
|
+
<% end %>
|
49
|
+
<% end %>
|
53
50
|
<% end %>
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
<%= render partial: "avo/partials/scripts" %>
|
58
|
-
<!-- Avo version: <%= Avo::VERSION %> -->
|
59
|
-
</body>
|
51
|
+
<%= render partial: "avo/partials/scripts" %>
|
52
|
+
<!-- Avo version: <%= Avo::VERSION %> -->
|
53
|
+
</body>
|
60
54
|
</html>
|
data/db/factories.rb
CHANGED
@@ -25,7 +25,6 @@ FactoryBot.define do
|
|
25
25
|
Time.now - rand(10...365).days
|
26
26
|
end
|
27
27
|
end
|
28
|
-
tag_list { ["1", "2", "five", "seven"].shuffle }
|
29
28
|
status { ::Post.statuses.keys.sample }
|
30
29
|
end
|
31
30
|
|
@@ -65,7 +64,6 @@ FactoryBot.define do
|
|
65
64
|
|
66
65
|
factory :course do
|
67
66
|
name { Faker::Educator.unique.course_name }
|
68
|
-
skills { [Faker::Educator.subject, Faker::Educator.subject, Faker::Educator.subject, Faker::Educator.subject, Faker::Educator.subject] }
|
69
67
|
country { Course.countries.sample }
|
70
68
|
city { Course.cities.stringify_keys[country].sample }
|
71
69
|
end
|
data/lib/avo/base_action.rb
CHANGED
@@ -61,8 +61,7 @@ module Avo
|
|
61
61
|
self.class.cancel_button_label ||= I18n.t("avo.cancel")
|
62
62
|
|
63
63
|
@response ||= {}
|
64
|
-
@response[:
|
65
|
-
@response[:message] ||= I18n.t("avo.action_ran_successfully")
|
64
|
+
@response[:messages] = []
|
66
65
|
end
|
67
66
|
|
68
67
|
def context
|
@@ -131,15 +130,25 @@ module Avo
|
|
131
130
|
end
|
132
131
|
|
133
132
|
def succeed(text)
|
134
|
-
|
135
|
-
response[:message] = text
|
133
|
+
add_message text, :success
|
136
134
|
|
137
135
|
self
|
138
136
|
end
|
139
137
|
|
140
138
|
def fail(text)
|
141
|
-
|
142
|
-
|
139
|
+
add_message text, :error
|
140
|
+
|
141
|
+
self
|
142
|
+
end
|
143
|
+
|
144
|
+
def inform(text)
|
145
|
+
add_message text, :info
|
146
|
+
|
147
|
+
self
|
148
|
+
end
|
149
|
+
|
150
|
+
def warn(text)
|
151
|
+
add_message text, :warning
|
143
152
|
|
144
153
|
self
|
145
154
|
end
|
@@ -168,5 +177,14 @@ module Avo
|
|
168
177
|
|
169
178
|
self
|
170
179
|
end
|
180
|
+
|
181
|
+
private
|
182
|
+
|
183
|
+
def add_message(body, type = :info)
|
184
|
+
response[:messages] << {
|
185
|
+
type: type,
|
186
|
+
body: body
|
187
|
+
}
|
188
|
+
end
|
171
189
|
end
|
172
190
|
end
|
data/lib/avo/base_resource.rb
CHANGED
data/lib/avo/engine.rb
CHANGED
@@ -4,9 +4,8 @@ module Avo
|
|
4
4
|
extend ActiveSupport::DescendantsTracker
|
5
5
|
extend Avo::Fields::FieldExtensions::HasFieldName
|
6
6
|
|
7
|
-
include Avo::Fields::FieldExtensions::VisibleInDifferentViews
|
8
|
-
include Avo::Concerns::HandlesFieldArgs
|
9
7
|
include ActionView::Helpers::UrlHelper
|
8
|
+
include Avo::Fields::FieldExtensions::VisibleInDifferentViews
|
10
9
|
|
11
10
|
delegate :view_context, to: "Avo::App"
|
12
11
|
delegate :main_app, to: :view_context
|
@@ -4,10 +4,10 @@ module Avo
|
|
4
4
|
attr_accessor :relation_method
|
5
5
|
|
6
6
|
def initialize(id, **args, &block)
|
7
|
-
super(id, **args, &block)
|
8
|
-
|
9
7
|
hide_on :new, :edit
|
10
8
|
|
9
|
+
super(id, **args, &block)
|
10
|
+
|
11
11
|
@placeholder ||= I18n.t "avo.choose_an_option"
|
12
12
|
|
13
13
|
@relation_method = name.to_s.parameterize.underscore
|
data/lib/avo/version.rb
CHANGED