avo 1.6.0 → 1.6.3.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 +1 -1
- data/Gemfile.lock +6 -6
- data/app/components/avo/edit/field_wrapper_component.html.erb +1 -1
- data/app/components/avo/edit/field_wrapper_component.rb +6 -1
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +65 -15
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +1 -1
- data/app/controllers/avo/application_controller.rb +5 -5
- data/app/controllers/avo/base_controller.rb +8 -0
- data/app/packs/js/controllers/fields/belongs_to_field_controller.js +65 -0
- data/db/factories.rb +4 -0
- data/lib/avo/base_resource.rb +36 -19
- data/lib/avo/configuration.rb +7 -1
- data/lib/avo/fields/base_field.rb +5 -3
- data/lib/avo/fields/belongs_to_field.rb +95 -11
- data/lib/avo/fields/boolean_group_field.rb +1 -1
- data/lib/avo/fields/date_time_field.rb +1 -1
- data/lib/avo/fields/files_field.rb +1 -1
- data/lib/avo/fields/has_one_field.rb +1 -1
- data/lib/avo/fields/key_value_field.rb +1 -1
- data/lib/avo/fields_collector.rb +0 -2
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/initializer/avo.tt +1 -1
- data/lib/generators/avo/tool_generator.rb +8 -2
- data/public/avo-packs/css/application-797341b7.css.map +1 -1
- data/public/avo-packs/css/application-797341b7.css.map.br +0 -0
- data/public/avo-packs/css/application-797341b7.css.map.gz +0 -0
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js +26 -0
- data/public/avo-packs/js/{application-b444cbf11135b4b23654.js.LICENSE.txt → application-947ed727440d5b5d73ab.js.LICENSE.txt} +0 -0
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.br +0 -0
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.gz +0 -0
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.map +1 -0
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.map.br +0 -0
- data/public/avo-packs/js/application-947ed727440d5b5d73ab.js.map.gz +0 -0
- data/public/avo-packs/manifest.json +8 -8
- metadata +12 -11
- data/public/avo-packs/js/application-b444cbf11135b4b23654.js +0 -26
- data/public/avo-packs/js/application-b444cbf11135b4b23654.js.br +0 -0
- data/public/avo-packs/js/application-b444cbf11135b4b23654.js.gz +0 -0
- data/public/avo-packs/js/application-b444cbf11135b4b23654.js.map +0 -1
- data/public/avo-packs/js/application-b444cbf11135b4b23654.js.map.br +0 -0
- data/public/avo-packs/js/application-b444cbf11135b4b23654.js.map.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 223442cb4814fbbdbac19b17f00ccfd5db95c1020137010e9393aa24898a7d35
|
4
|
+
data.tar.gz: fcec7fbe1391bd73ef39b8f8f58643a473c0c9c0349ddddfd0e737e3fcaa0f4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed74295ce9b330ff686202d2ad75ec0120d32ccbc43437ea6eb1a81a365895fb7b43948d734221d0a71b8a987fd8670b0951020ad22107167760548c52a020d0
|
7
|
+
data.tar.gz: 2b826242331414096f2260d62fb25749456d9f7e2ccaa02a6a467d2de146e77224f462ea17dec59c492b9997fad36d5ffa1f036066859f5fea0f177c7e8a863e
|
data/Gemfile
CHANGED
@@ -30,7 +30,7 @@ gem "rails", "~> 6.0.2", ">= 6.0.2.2"
|
|
30
30
|
# Use postgresql as the database for Active Record
|
31
31
|
gem "pg", ">= 0.18", "< 2.0"
|
32
32
|
# Use Puma as the app server
|
33
|
-
gem "puma", "~>
|
33
|
+
gem "puma", "~> 5.3.1"
|
34
34
|
# Use SCSS for stylesheets
|
35
35
|
gem "sass-rails", ">= 6"
|
36
36
|
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
avo (1.6.
|
4
|
+
avo (1.6.3.pre.3)
|
5
5
|
active_link_to
|
6
6
|
addressable
|
7
7
|
breadcrumbs_on_rails
|
@@ -184,10 +184,10 @@ GEM
|
|
184
184
|
msgpack (1.4.2)
|
185
185
|
multi_xml (0.6.0)
|
186
186
|
nio4r (2.5.7)
|
187
|
-
nokogiri (1.11.
|
187
|
+
nokogiri (1.11.5)
|
188
188
|
mini_portile2 (~> 2.5.0)
|
189
189
|
racc (~> 1.4)
|
190
|
-
nokogiri (1.11.
|
190
|
+
nokogiri (1.11.5-x86_64-linux)
|
191
191
|
racc (~> 1.4)
|
192
192
|
orm_adapter (0.5.0)
|
193
193
|
pagy (3.13.0)
|
@@ -196,7 +196,7 @@ GEM
|
|
196
196
|
ast (~> 2.4.1)
|
197
197
|
pg (1.2.3)
|
198
198
|
public_suffix (4.0.6)
|
199
|
-
puma (
|
199
|
+
puma (5.3.1)
|
200
200
|
nio4r (~> 2.0)
|
201
201
|
pundit (2.1.0)
|
202
202
|
activesupport (>= 3.0.0)
|
@@ -333,7 +333,7 @@ GEM
|
|
333
333
|
thread_safe (~> 0.1)
|
334
334
|
unicode-display_width (2.0.0)
|
335
335
|
unicode_utils (1.4.0)
|
336
|
-
view_component (2.
|
336
|
+
view_component (2.32.0)
|
337
337
|
activesupport (>= 5.0.0, < 7.0)
|
338
338
|
warden (1.2.9)
|
339
339
|
rack (>= 2.0.9)
|
@@ -394,7 +394,7 @@ DEPENDENCIES
|
|
394
394
|
manifester
|
395
395
|
meta-tags
|
396
396
|
pg (>= 0.18, < 2.0)
|
397
|
-
puma (~>
|
397
|
+
puma (~> 5.3.1)
|
398
398
|
pundit
|
399
399
|
rails (~> 6.0.2, >= 6.0.2.2)
|
400
400
|
rails-controller-testing
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="flex items-center py-0 leading-tight <%= @classes %> min-h-16" data-field-id="<%= @field.id %>" data-field-type="<%= @field.type %>">
|
2
2
|
<div class="h-16 flex self-start items-center text-blue-gray-800">
|
3
3
|
<div class="<% if @displayed_in_modal %> md:w-48 <% else %> md:w-64 <% end %> w-48 px-8 flex" data-slot="label">
|
4
|
-
<%= @form.label @field.id,
|
4
|
+
<%= @form.label @field.id, label %> <% if @field.required %> <span class="text-red-600">*</span> <% end %>
|
5
5
|
</div>
|
6
6
|
</div>
|
7
7
|
<div class="flex-1 flex flex-row min-h-inherit">
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Avo::Edit::FieldWrapperComponent < ViewComponent::Base
|
4
|
-
def initialize(field: nil, dash_if_blank: true, full_width: false, displayed_in_modal: false, form: nil, resource: {}, **args)
|
4
|
+
def initialize(field: nil, dash_if_blank: true, full_width: false, displayed_in_modal: false, form: nil, resource: {}, label: nil, **args)
|
5
5
|
@field = field
|
6
6
|
@dash_if_blank = dash_if_blank
|
7
7
|
@classes = args[:class].present? ? args[:class] : ""
|
@@ -11,9 +11,14 @@ class Avo::Edit::FieldWrapperComponent < ViewComponent::Base
|
|
11
11
|
@resource = resource
|
12
12
|
@model = resource.present? ? resource.model : nil
|
13
13
|
@full_width = full_width
|
14
|
+
@label = label
|
14
15
|
|
15
16
|
if (@index != 0) || @displayed_in_modal
|
16
17
|
@classes += " border-t"
|
17
18
|
end
|
18
19
|
end
|
20
|
+
|
21
|
+
def label
|
22
|
+
@label || @field.name
|
23
|
+
end
|
19
24
|
end
|
@@ -1,18 +1,68 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
<% if @field.types.present? %>
|
2
|
+
<div data-controller="belongs-to-field">
|
3
|
+
<%= edit_field_wrapper field: @field, index: @index, form: @form, resource: @resource, displayed_in_modal: @displayed_in_modal do %>
|
4
|
+
<%= @form.select "#{@field.foreign_key}_type", @field.types.map { |type| [type.to_s.humanize, type.to_s] },
|
5
|
+
{
|
6
|
+
include_blank: @field.placeholder,
|
7
|
+
},
|
8
|
+
{
|
9
|
+
class: helpers.input_classes('w-full', has_error: @field.model_errors.include?(@field.id)),
|
10
|
+
disabled: disabled,
|
11
|
+
'data-belongs-to-field-target': "select",
|
12
|
+
'data-action': 'change->belongs-to-field#changedType'
|
13
|
+
}
|
14
|
+
%>
|
15
|
+
<%
|
16
|
+
# If the select field is disabled, no value will be sent. It's how HTML works.
|
17
|
+
# Thus the extra hidden field to actually send the related id to the server.
|
18
|
+
if disabled
|
19
|
+
%>
|
20
|
+
<%= @form.hidden_field "#{@field.foreign_key}_type" %>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
23
|
+
<% @field.types.each do |type| %>
|
24
|
+
<div class="hidden"
|
25
|
+
data-belongs-to-field-target="type"
|
26
|
+
data-type="<%= type %>"
|
27
|
+
>
|
28
|
+
<%= edit_field_wrapper field: @field, index: @index, form: @form, resource: @resource, displayed_in_modal: @displayed_in_modal, label: type.to_s do %>
|
29
|
+
<%= @form.select "#{@field.foreign_key}_id", @field.values_for_type(type),
|
30
|
+
{
|
31
|
+
include_blank: @field.placeholder,
|
32
|
+
},
|
33
|
+
{
|
34
|
+
class: helpers.input_classes('w-full', has_error: @field.model_errors.include?(@field.id)),
|
35
|
+
disabled: disabled
|
36
|
+
}
|
37
|
+
%>
|
38
|
+
<%
|
39
|
+
# If the select field is disabled, no value will be sent. It's how HTML works.
|
40
|
+
# Thus the extra hidden field to actually send the related id to the server.
|
41
|
+
if disabled
|
42
|
+
%>
|
43
|
+
<%= @form.hidden_field "#{@field.foreign_key}_id" %>
|
44
|
+
<% end %>
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
49
|
+
<% else %>
|
50
|
+
<%= edit_field_wrapper field: @field, index: @index, form: @form, resource: @resource, displayed_in_modal: @displayed_in_modal do %>
|
51
|
+
<%= @form.select @field.foreign_key, @field.options.map { |o| [o[:label], o[:value]] },
|
52
|
+
{
|
53
|
+
include_blank: @field.placeholder,
|
54
|
+
},
|
55
|
+
{
|
56
|
+
class: helpers.input_classes('w-full', has_error: @field.model_errors.include?(@field.id)),
|
57
|
+
disabled: disabled
|
58
|
+
}
|
59
|
+
%>
|
60
|
+
<%
|
61
|
+
# If the select field is disabled, no value will be sent. It's how HTML works.
|
62
|
+
# Thus the extra hidden field to actually send the related id to the server.
|
63
|
+
if disabled
|
10
64
|
%>
|
11
|
-
|
12
|
-
|
13
|
-
# Thus the extra hidden field to actually send the related id to the server.
|
14
|
-
if disabled
|
15
|
-
%>
|
16
|
-
<%= @form.hidden_field @field.foreign_key %>
|
65
|
+
<%= @form.hidden_field @field.foreign_key %>
|
66
|
+
<% end %>
|
17
67
|
<% end %>
|
18
68
|
<% end %>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
class Avo::Fields::BelongsToField::EditComponent < Avo::Fields::EditComponent
|
4
4
|
def disabled
|
5
5
|
return true if @field.readonly
|
6
|
-
return true if @field.target_resource.model_class.name == params[:via_resource_class]
|
6
|
+
return true if @field.target_resource.present? && @field.target_resource.model_class.name == params[:via_resource_class]
|
7
7
|
return true if @field.id.to_s == params[:via_relation].to_s
|
8
8
|
|
9
9
|
false
|
@@ -52,11 +52,11 @@ module Avo
|
|
52
52
|
if @license.lacks(:custom_tools) || @license.invalid?
|
53
53
|
if Rails.env.development? || Rails.env.test?
|
54
54
|
@custom_tools_alert_visible = true
|
55
|
+
elsif @license.lacks_with_trial(:custom_tools)
|
56
|
+
# Raise error in non-development environments.
|
57
|
+
raise Avo::LicenseInvalidError, "Your license is invalid or doesn't support custom tools."
|
55
58
|
end
|
56
59
|
end
|
57
|
-
|
58
|
-
# Raise error in non-development environments.
|
59
|
-
raise Avo::LicenseInvalidError, "Your license is invalid or doesn't support custom tools." if @license.lacks_with_trial(:custom_tools)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -277,11 +277,11 @@ module Avo
|
|
277
277
|
end
|
278
278
|
|
279
279
|
def on_resources_path
|
280
|
-
request.original_url.match?(
|
280
|
+
request.original_url.match?(/.*#{Avo.configuration.root_path}\/resources\/.*/)
|
281
281
|
end
|
282
282
|
|
283
283
|
def on_api_path
|
284
|
-
request.original_url.match?(
|
284
|
+
request.original_url.match?(/.*#{Avo.configuration.root_path}\/avo_api\/.*/)
|
285
285
|
end
|
286
286
|
end
|
287
287
|
end
|
@@ -167,6 +167,14 @@ module Avo
|
|
167
167
|
|
168
168
|
def permitted_params
|
169
169
|
@resource.get_field_definitions.select(&:updatable).map(&:to_permitted_param)
|
170
|
+
# ppp = []
|
171
|
+
|
172
|
+
# @resource.get_field_definitions.select(&:updatable).each do |param|
|
173
|
+
# ppp.push(*param.to_permitted_param)
|
174
|
+
# end
|
175
|
+
# # abort ppp.inspect
|
176
|
+
# puts [':ppp ->', ppp].inspect
|
177
|
+
# ppp
|
170
178
|
end
|
171
179
|
|
172
180
|
def cast_nullable(params)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { Controller } from 'stimulus'
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ['select', 'type']
|
5
|
+
|
6
|
+
get selectedType() {
|
7
|
+
return this.selectTarget.value
|
8
|
+
}
|
9
|
+
|
10
|
+
connect() {
|
11
|
+
this.setValidNames()
|
12
|
+
this.changedType()
|
13
|
+
}
|
14
|
+
|
15
|
+
setValidNames() {
|
16
|
+
this.typeTargets.forEach((target) => {
|
17
|
+
const { type } = target.dataset
|
18
|
+
const select = target.querySelector('select')
|
19
|
+
const name = select.getAttribute('name')
|
20
|
+
|
21
|
+
select.setAttribute('valid-name', name)
|
22
|
+
if (this.selectedType !== type) {
|
23
|
+
select.selectedIndex = 0
|
24
|
+
}
|
25
|
+
})
|
26
|
+
}
|
27
|
+
|
28
|
+
changedType() {
|
29
|
+
this.hideAllTypeTargets()
|
30
|
+
this.enableType(this.selectTarget.value)
|
31
|
+
}
|
32
|
+
|
33
|
+
hideAllTypeTargets() {
|
34
|
+
this.typeTargets.forEach((target) => {
|
35
|
+
this.hideTarget(target)
|
36
|
+
this.invalidateTarget(target)
|
37
|
+
})
|
38
|
+
}
|
39
|
+
|
40
|
+
hideTarget(target) {
|
41
|
+
target.classList.add('hidden')
|
42
|
+
}
|
43
|
+
|
44
|
+
invalidateTarget(target) {
|
45
|
+
const select = target.querySelector('select')
|
46
|
+
|
47
|
+
select.setAttribute('name', '')
|
48
|
+
}
|
49
|
+
|
50
|
+
validateTarget(target) {
|
51
|
+
const select = target.querySelector('select')
|
52
|
+
const validName = select.getAttribute('valid-name')
|
53
|
+
|
54
|
+
select.setAttribute('name', validName)
|
55
|
+
}
|
56
|
+
|
57
|
+
enableType(type) {
|
58
|
+
const target = this.typeTargets.find((typeTarget) => typeTarget.dataset.type === type)
|
59
|
+
|
60
|
+
if (target) {
|
61
|
+
target.classList.remove('hidden')
|
62
|
+
this.validateTarget(target)
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
data/db/factories.rb
CHANGED
@@ -40,4 +40,8 @@ FactoryBot.define do
|
|
40
40
|
meta { [{foo: "bar", hey: "hi"}, {bar: "baz"}, {hoho: "hohoho"}].sample }
|
41
41
|
progress { Faker::Number.between(from: 0, to: 100) }
|
42
42
|
end
|
43
|
+
|
44
|
+
factory :comment do
|
45
|
+
body { Faker::Lorem.paragraphs(number: rand(4...10)).join("\n") }
|
46
|
+
end
|
43
47
|
end
|
data/lib/avo/base_resource.rb
CHANGED
@@ -87,20 +87,31 @@ module Avo
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def get_fields(panel: nil, reflection: nil)
|
90
|
-
fields = get_field_definitions
|
91
|
-
field
|
92
|
-
|
90
|
+
fields = get_field_definitions
|
91
|
+
.select do |field|
|
92
|
+
field.send("show_on_#{@view}")
|
93
|
+
end
|
93
94
|
.select do |field|
|
94
|
-
|
95
|
-
|
95
|
+
field.visible?
|
96
|
+
end
|
96
97
|
.select do |field|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
98
|
+
# Strip out the reflection field in index queries with a parent association.
|
99
|
+
if reflection.present? &&
|
100
|
+
reflection.options.present? &&
|
101
|
+
field.respond_to?(:polymorphic_as) &&
|
102
|
+
field.polymorphic_as.to_s == reflection.options[:as].to_s
|
103
|
+
next
|
104
|
+
end
|
105
|
+
# if !field.respond_to?(:polymorphic_as) &&
|
106
|
+
# field.respond_to?(:foreign_key) &&
|
107
|
+
# reflection.present? &&
|
108
|
+
# reflection.respond_to?(:foreign_key) &&
|
109
|
+
# reflection.foreign_key != field.foreign_key
|
110
|
+
# next
|
111
|
+
# end
|
112
|
+
|
101
113
|
true
|
102
114
|
end
|
103
|
-
end
|
104
115
|
|
105
116
|
if panel.present?
|
106
117
|
fields = fields.select do |field|
|
@@ -250,14 +261,17 @@ module Avo
|
|
250
261
|
.reject do |field|
|
251
262
|
field.computed
|
252
263
|
end
|
253
|
-
.map
|
264
|
+
.map do |field|
|
265
|
+
[field.database_id(model).to_s, field]
|
266
|
+
end
|
267
|
+
.to_h
|
254
268
|
|
255
269
|
params.each do |key, value|
|
256
270
|
field = fields_by_database_id[key]
|
257
271
|
|
258
272
|
next unless field.present?
|
259
273
|
|
260
|
-
model = field.fill_field model, key, value
|
274
|
+
model = field.fill_field model, key, value, params
|
261
275
|
end
|
262
276
|
|
263
277
|
model
|
@@ -295,19 +309,22 @@ module Avo
|
|
295
309
|
|
296
310
|
# We will not overwrite any attributes that come pre-filled in the model.
|
297
311
|
def hydrate_model_with_default_values
|
298
|
-
default_values = get_fields
|
299
|
-
|
300
|
-
|
312
|
+
default_values = get_fields
|
313
|
+
.select do |field|
|
314
|
+
!field.computed
|
315
|
+
end
|
301
316
|
.map do |field|
|
302
317
|
id = field.id
|
303
318
|
value = field.value
|
304
319
|
|
305
|
-
if field.
|
320
|
+
if field.type == "belongs_to"
|
306
321
|
id = field.foreign_key.to_sym
|
307
322
|
|
308
323
|
reflection = @model._reflections[@params[:via_relation]]
|
309
324
|
|
310
|
-
if
|
325
|
+
if field.polymorphic_as.present? && field.types.map(&:to_s).include?(@params["via_relation_class"])
|
326
|
+
value = @params["via_relation_class"].safe_constantize.find(@params[:via_resource_id])
|
327
|
+
elsif reflection.present? && reflection.foreign_key.present? && field.id.to_s == @params[:via_relation].to_s
|
311
328
|
value = @params[:via_resource_id]
|
312
329
|
end
|
313
330
|
end
|
@@ -316,8 +333,8 @@ module Avo
|
|
316
333
|
end
|
317
334
|
.to_h
|
318
335
|
.select do |id, value|
|
319
|
-
|
320
|
-
|
336
|
+
value.present?
|
337
|
+
end
|
321
338
|
|
322
339
|
default_values.each do |id, value|
|
323
340
|
if @model.send(id).nil?
|
data/lib/avo/configuration.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Avo
|
2
2
|
class Configuration
|
3
|
-
|
3
|
+
attr_writer :root_path
|
4
4
|
attr_accessor :app_name
|
5
5
|
attr_accessor :timezone
|
6
6
|
attr_accessor :per_page
|
@@ -93,6 +93,12 @@ module Avo
|
|
93
93
|
def namespace
|
94
94
|
root_path.delete "/"
|
95
95
|
end
|
96
|
+
|
97
|
+
def root_path
|
98
|
+
return "" if @root_path === "/"
|
99
|
+
|
100
|
+
@root_path
|
101
|
+
end
|
96
102
|
end
|
97
103
|
|
98
104
|
def self.configuration
|
@@ -91,9 +91,11 @@ module Avo
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
def value
|
94
|
+
def value(property = nil)
|
95
|
+
property ||= id
|
96
|
+
|
95
97
|
# Get model value
|
96
|
-
final_value = @model.send(
|
98
|
+
final_value = @model.send(property) if (model_or_class(@model) == "model") && @model.respond_to?(property)
|
97
99
|
|
98
100
|
if (@view === :new) || @action.present?
|
99
101
|
final_value = if default.present? && default.respond_to?(:call)
|
@@ -114,7 +116,7 @@ module Avo
|
|
114
116
|
final_value
|
115
117
|
end
|
116
118
|
|
117
|
-
def fill_field(model, key, value)
|
119
|
+
def fill_field(model, key, value, params)
|
118
120
|
return model unless model.methods.include? key.to_sym
|
119
121
|
|
120
122
|
model.send("#{key}=", value)
|