pg_rails 7.0.2 → 7.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/pg_associable/app/assets/js/asociable_controller.js +3 -4
- data/pg_associable/app/assets/js/asociable_inline_controller.js +28 -27
- data/pg_associable/app/assets/js/modal_controller.js +31 -44
- data/pg_associable/app/helpers/pg_associable/helpers.rb +2 -2
- data/pg_associable/app/views/pg_engine/base/_pg_associable_modal.html.slim +4 -2
- data/pg_associable/spec/pg_associable/helpers_spec.rb +24 -0
- data/pg_engine/app/controllers/pg_engine/base_controller.rb +0 -283
- data/pg_engine/app/controllers/pg_engine/require_sign_in.rb +9 -0
- data/pg_engine/app/controllers/pg_engine/resource_helper.rb +289 -0
- data/pg_engine/app/helpers/pg_engine/flash_helper.rb +3 -1
- data/pg_engine/app/helpers/pg_engine/route_helper.rb +2 -0
- data/pg_engine/app/views/pg_engine/base/index.html.slim +1 -1
- data/pg_engine/lib/pg_engine/engine.rb +5 -1
- data/pg_engine/lib/pg_engine/route_helpers.rb +12 -0
- data/pg_engine/lib/pg_engine/utils/pg_logger.rb +44 -0
- data/pg_engine/lib/pg_engine.rb +2 -12
- data/pg_layout/app/assets/stylesheets/sidebar.scss +4 -0
- data/pg_layout/app/views/layouts/pg_layout/devise.html.slim +2 -2
- data/pg_layout/app/views/layouts/pg_layout/layout.html.slim +2 -1
- data/pg_layout/app/views/pg_layout/_navbar.html.erb +0 -8
- data/pg_layout/index.js +3 -2
- data/pg_rails/lib/version.rb +1 -1
- data/pg_scaffold/lib/generators/pg_active_record/model/templates/admin.rb +1 -1
- data/pg_scaffold/lib/generators/pg_active_record/model/templates/model.rb +0 -1
- data/pg_scaffold/lib/generators/pg_resource_route/pg_resource_route_generator.rb +1 -1
- data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/controller_spec.rb +7 -0
- data/pg_scaffold/lib/generators/pg_scaffold/pg_scaffold_generator.rb +5 -9
- data/pg_scaffold/lib/generators/pg_scaffold/templates/controller.rb +6 -4
- data/pg_scaffold/spec/generators_spec.rb +55 -0
- metadata +8 -4
- data/pg_engine/app/controllers/pg_engine/signed_in_controller.rb +0 -7
- data/pg_engine/lib/pg_engine/utils/logueador.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f938c5e60b8cb063472ebc6a8f42445714d5e2ade2b86d2863b9a98d7bd8eb32
|
4
|
+
data.tar.gz: abea2aba977e1ed3c33a4d0e39e27e84943a0a3066514e1123bec424c03d2014
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1383e921c7de060743dfa1d2d4f68c9bd0b8308cb72c35ed5a41beac46b007281de7427fae3c52930b31f8c77a853c62b4cdf5774d95d5f27ef3fa110e8c1e0b
|
7
|
+
data.tar.gz: dbb40317f97d3d7678140e6d5c92bfdd70119e1eda35093d55d33fe2364156718fcd8a45bebd27ba2c7c388760ef269b594f0c17d65c8c02b6c79eab97c22ac1
|
@@ -26,21 +26,20 @@ export default class extends Controller {
|
|
26
26
|
}
|
27
27
|
}
|
28
28
|
const input = this.element.querySelector('input[type=text]')
|
29
|
-
if(input.value) {
|
29
|
+
if (input.value) {
|
30
30
|
this.element.classList.add('filled')
|
31
31
|
}
|
32
|
-
|
33
32
|
}
|
34
33
|
|
35
|
-
|
36
34
|
selectItem (e) {
|
37
35
|
// TODO: text en data
|
38
36
|
this.completarCampo(e.target.dataset.id, e.target.text)
|
39
37
|
}
|
38
|
+
|
40
39
|
completarCampo (id, text) {
|
41
40
|
const textField = this.element.querySelector('input[type=text]')
|
42
41
|
const hiddenField = this.element.querySelector('input[type=hidden]')
|
43
|
-
if(
|
42
|
+
if (id === undefined) {
|
44
43
|
id = null
|
45
44
|
}
|
46
45
|
hiddenField.value = id
|
@@ -22,86 +22,88 @@ export default class extends Controller {
|
|
22
22
|
this.element.querySelector('.pencil').onclick = (e) => {
|
23
23
|
that.input.focus()
|
24
24
|
}
|
25
|
-
if(this.input.value) {
|
25
|
+
if (this.input.value) {
|
26
26
|
this.element.classList.add('filled')
|
27
27
|
}
|
28
28
|
|
29
|
-
|
30
|
-
let timerId
|
29
|
+
const debounce = function (callback, wait) {
|
30
|
+
let timerId
|
31
31
|
return (...args) => {
|
32
|
-
clearTimeout(timerId)
|
32
|
+
clearTimeout(timerId)
|
33
33
|
timerId = setTimeout(() => {
|
34
|
-
callback(...args)
|
35
|
-
}, wait)
|
36
|
-
}
|
34
|
+
callback(...args)
|
35
|
+
}, wait)
|
36
|
+
}
|
37
37
|
}
|
38
38
|
const doSearchBounce = debounce((force) => {
|
39
39
|
that.doSearch(force)
|
40
40
|
}, 200)
|
41
41
|
|
42
42
|
this.input.addEventListener('blur', (e) => {
|
43
|
-
this.input.placeholder =
|
43
|
+
this.input.placeholder = ''
|
44
44
|
})
|
45
45
|
this.input.onfocus = (e) => {
|
46
46
|
this.input.select()
|
47
|
-
if(this.input.value.length
|
47
|
+
if (this.input.value.length === 0) {
|
48
48
|
this.escribiAlgo()
|
49
49
|
}
|
50
50
|
}
|
51
51
|
this.input.onkeyup = (e) => {
|
52
|
-
if(this.input.value.length
|
52
|
+
if (this.input.value.length === 0) {
|
53
53
|
this.escribiAlgo()
|
54
54
|
}
|
55
|
-
if(e.keyCode
|
55
|
+
if (e.keyCode === 13) {
|
56
56
|
doSearchBounce(true)
|
57
57
|
} else {
|
58
58
|
doSearchBounce()
|
59
59
|
}
|
60
60
|
}
|
61
61
|
this.input.onkeydown = (e) => {
|
62
|
-
if(e.keyCode
|
63
|
-
e.preventDefault()
|
64
|
-
return false
|
62
|
+
if (e.keyCode === 13) {
|
63
|
+
e.preventDefault()
|
64
|
+
return false
|
65
65
|
}
|
66
66
|
}
|
67
67
|
}
|
68
|
-
|
68
|
+
|
69
|
+
buscando () {
|
69
70
|
this.result.innerHTML = `
|
70
71
|
<div class="resultados" tabindex="-1">
|
71
72
|
<div class="fst-italic text-secondary">Buscando...</div>
|
72
73
|
</div>
|
73
74
|
`
|
74
75
|
}
|
75
|
-
|
76
|
-
|
76
|
+
|
77
|
+
escribiAlgo () {
|
78
|
+
this.input.placeholder = 'Escribí algo para buscar'
|
77
79
|
}
|
78
80
|
|
79
|
-
doSearch(force = false) {
|
80
|
-
if(!force && this.input.value.length < 3) {
|
81
|
+
doSearch (force = false) {
|
82
|
+
if (!force && this.input.value.length < 3) {
|
81
83
|
return
|
82
84
|
}
|
83
|
-
if(!force && this.input.value
|
85
|
+
if (!force && this.input.value === this.lastValue) {
|
84
86
|
return
|
85
87
|
}
|
86
88
|
this.lastValue = this.input.value
|
87
89
|
|
88
|
-
|
90
|
+
const timerId = setTimeout(() => {
|
89
91
|
this.buscando()
|
90
92
|
}, 200)
|
91
|
-
document.addEventListener(
|
93
|
+
document.addEventListener('turbo:before-stream-render', function (e) {
|
92
94
|
clearTimeout(timerId)
|
93
95
|
})
|
94
|
-
|
96
|
+
const url = `${this.input.dataset.url}?id=${this.elemId}`
|
95
97
|
const form = document.createElement('form')
|
96
98
|
form.setAttribute('method', 'post')
|
97
99
|
form.setAttribute('action', url)
|
98
100
|
form.setAttribute('data-turbo-stream', true)
|
99
|
-
|
101
|
+
const partial = document.createElement('input')
|
100
102
|
partial.setAttribute('type', 'hidden')
|
101
103
|
partial.setAttribute('name', 'partial')
|
102
104
|
partial.setAttribute('value', 'pg_associable/resultados_inline')
|
103
105
|
form.appendChild(partial)
|
104
|
-
|
106
|
+
const query = document.createElement('input')
|
105
107
|
query.setAttribute('type', 'hidden')
|
106
108
|
query.setAttribute('name', 'query')
|
107
109
|
query.setAttribute('value', this.input.value)
|
@@ -114,7 +116,7 @@ export default class extends Controller {
|
|
114
116
|
completarCampo (id, text) {
|
115
117
|
const textField = this.element.querySelector('input[type=text]')
|
116
118
|
const hiddenField = this.element.querySelector('input[type=hidden]')
|
117
|
-
if(
|
119
|
+
if (id === undefined) {
|
118
120
|
id = null
|
119
121
|
}
|
120
122
|
hiddenField.value = id
|
@@ -134,7 +136,6 @@ export default class extends Controller {
|
|
134
136
|
this.result.innerHTML = ''
|
135
137
|
}
|
136
138
|
|
137
|
-
|
138
139
|
disconnect (e) {
|
139
140
|
console.log('disconnect asociable_inline')
|
140
141
|
}
|
@@ -3,10 +3,9 @@ import * as bootstrap from 'bootstrap'
|
|
3
3
|
|
4
4
|
export default class extends Controller {
|
5
5
|
static outlets = ['asociable']
|
6
|
-
static targets = ['response', 'result']
|
6
|
+
static targets = ['response', 'result', 'searchInput', 'searchForm']
|
7
7
|
|
8
8
|
modalPuntero = null
|
9
|
-
input = null
|
10
9
|
lastValue = ''
|
11
10
|
|
12
11
|
connect (e) {
|
@@ -15,28 +14,33 @@ export default class extends Controller {
|
|
15
14
|
this.modalPuntero = new bootstrap.Modal(modal)
|
16
15
|
this.modalPuntero.show()
|
17
16
|
|
18
|
-
this.
|
17
|
+
if (this.searchInputTargets.length > 0) {
|
18
|
+
this.bindSearchInput()
|
19
|
+
}
|
20
|
+
}
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
};
|
22
|
+
debounce (callback, wait) {
|
23
|
+
let timerId
|
24
|
+
return (...args) => {
|
25
|
+
clearTimeout(timerId)
|
26
|
+
timerId = setTimeout(() => {
|
27
|
+
callback(...args)
|
28
|
+
}, wait)
|
28
29
|
}
|
29
|
-
|
30
|
+
}
|
31
|
+
|
32
|
+
bindSearchInput () {
|
33
|
+
const doSearchBounce = this.debounce((force) => {
|
30
34
|
this.doSearch(force)
|
31
35
|
}, 200)
|
32
|
-
this.
|
33
|
-
if(e.keyCode
|
34
|
-
e.preventDefault()
|
35
|
-
return false
|
36
|
+
this.searchInputTarget.onkeydown = (e) => {
|
37
|
+
if (e.keyCode === 13) {
|
38
|
+
e.preventDefault()
|
39
|
+
return false
|
36
40
|
}
|
37
41
|
}
|
38
|
-
this.
|
39
|
-
if(e.keyCode
|
42
|
+
this.searchInputTarget.onkeyup = (e) => {
|
43
|
+
if (e.keyCode === 13) {
|
40
44
|
doSearchBounce(true)
|
41
45
|
} else {
|
42
46
|
doSearchBounce()
|
@@ -44,7 +48,7 @@ export default class extends Controller {
|
|
44
48
|
}
|
45
49
|
}
|
46
50
|
|
47
|
-
buscando() {
|
51
|
+
buscando () {
|
48
52
|
this.resultTarget.innerHTML = `
|
49
53
|
<ul class="resultados list-group list-group-flush" tabindex="-1">
|
50
54
|
<li class="list-group-item">
|
@@ -53,40 +57,23 @@ export default class extends Controller {
|
|
53
57
|
</ul>
|
54
58
|
`
|
55
59
|
}
|
56
|
-
|
57
|
-
|
60
|
+
|
61
|
+
doSearch (force = false) {
|
62
|
+
if (!force && this.searchInputTarget.value.length < 3) {
|
58
63
|
return
|
59
64
|
}
|
60
|
-
if(!force && this.
|
65
|
+
if (!force && this.searchInputTarget.value === this.lastValue) {
|
61
66
|
return
|
62
67
|
}
|
63
|
-
this.lastValue = this.
|
68
|
+
this.lastValue = this.searchInputTarget.value
|
64
69
|
|
65
|
-
|
70
|
+
const timerId = setTimeout(() => {
|
66
71
|
this.buscando()
|
67
72
|
}, 200)
|
68
|
-
document.addEventListener(
|
73
|
+
document.addEventListener('turbo:before-stream-render', function (e) {
|
69
74
|
clearTimeout(timerId)
|
70
75
|
})
|
71
|
-
this.
|
72
|
-
// let url = `${this.input.dataset.url}?id=${this.elemId}`
|
73
|
-
// const form = document.createElement('form')
|
74
|
-
// form.setAttribute('method', 'post')
|
75
|
-
// form.setAttribute('action', url)
|
76
|
-
// form.setAttribute('data-turbo-stream', true)
|
77
|
-
// let partial = document.createElement('input')
|
78
|
-
// partial.setAttribute('type', 'hidden')
|
79
|
-
// partial.setAttribute('name', 'partial')
|
80
|
-
// partial.setAttribute('value', 'pg_associable/resultados_inline')
|
81
|
-
// form.appendChild(partial)
|
82
|
-
// let query = document.createElement('input')
|
83
|
-
// query.setAttribute('type', 'hidden')
|
84
|
-
// query.setAttribute('name', 'query')
|
85
|
-
// query.setAttribute('value', this.input.value)
|
86
|
-
// form.appendChild(query)
|
87
|
-
// document.body.prepend(form)
|
88
|
-
// form.requestSubmit()
|
89
|
-
// form.remove()
|
76
|
+
this.searchFormTarget.requestSubmit()
|
90
77
|
}
|
91
78
|
|
92
79
|
selectItem (e) {
|
@@ -10,10 +10,10 @@ module PgAssociable
|
|
10
10
|
|
11
11
|
def pg_respond_buscar
|
12
12
|
partial = params[:partial] || 'pg_associable/resultados'
|
13
|
-
collection = @clase_modelo.query(params[:query]).limit(6)
|
13
|
+
@collection = policy_scope(@clase_modelo).kept.query(params[:query]).limit(6)
|
14
14
|
render turbo_stream:
|
15
15
|
turbo_stream.update("resultados-#{params[:id]}",
|
16
|
-
partial:, locals: { collection: })
|
16
|
+
partial:, locals: { collection: @collection })
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -11,17 +11,19 @@
|
|
11
11
|
a.btn-close[type="button" data-bs-dismiss="modal" aria-label="Close"]
|
12
12
|
.modal-body
|
13
13
|
.show-on-select-item
|
14
|
-
- if @clase_modelo.count.zero?
|
14
|
+
- if policy_scope(@clase_modelo).kept.count.zero?
|
15
15
|
p No hay #{@clase_modelo.nombre_plural.downcase} aún
|
16
16
|
= link_to "Crear el primer #{@clase_modelo.nombre_singular.downcase}",
|
17
17
|
'javascript:void(0)', data: { action: 'modal#toggleCrearElegir' }
|
18
18
|
- else
|
19
19
|
= form_tag namespaced_path(@clase_modelo, prefix: :buscar),
|
20
|
+
data: { 'modal-target': 'searchForm' },
|
20
21
|
method: :post, class: 'pg-form buscar' do
|
21
22
|
= hidden_field_tag :id, params[:id]
|
22
23
|
= text_field_tag :query, '', class: 'form-control',
|
23
24
|
placeholder: 'Escribí algo para buscar',
|
24
|
-
autocomplete: 'off'
|
25
|
+
autocomplete: 'off',
|
26
|
+
data: { 'modal-target': 'searchInput' }
|
25
27
|
/ = button_tag 'Buscar'
|
26
28
|
.resultados-wrapper id="resultados-#{params[:id]}" data-modal-target="result"
|
27
29
|
#pg-associable-form.show-on-new-item
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe PgAssociable::Helpers do
|
4
|
+
describe '#pg_respond_buscar' do
|
5
|
+
let(:user) { create :user }
|
6
|
+
let(:ctrl) do
|
7
|
+
clazz = Class.new(PgEngine::BaseController)
|
8
|
+
clazz.new
|
9
|
+
end
|
10
|
+
let!(:cosa) { create :cosa }
|
11
|
+
|
12
|
+
before do
|
13
|
+
allow(ctrl).to receive_messages(current_user: user, params: { id: 123, query: cosa.id })
|
14
|
+
allow(ctrl).to receive(:render)
|
15
|
+
ctrl.instance_variable_set(:@clase_modelo, Cosa)
|
16
|
+
end
|
17
|
+
|
18
|
+
it do
|
19
|
+
ctrl.pg_respond_buscar
|
20
|
+
cosas = ctrl.instance_variable_get(:@collection)
|
21
|
+
expect(cosas).to eq [cosa]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -17,8 +17,6 @@ module PgEngine
|
|
17
17
|
rescue_from Pundit::NotAuthorizedError, with: :not_authorized
|
18
18
|
|
19
19
|
helper_method :mobile_device?
|
20
|
-
helper_method :atributos_para_listar
|
21
|
-
helper_method :atributos_para_mostrar
|
22
20
|
|
23
21
|
layout 'pg_layout/layout'
|
24
22
|
|
@@ -36,251 +34,12 @@ module PgEngine
|
|
36
34
|
@navbar = Navbar.new(current_user)
|
37
35
|
end
|
38
36
|
|
39
|
-
# Public endpoints
|
40
|
-
def abrir_modal
|
41
|
-
pg_respond_abrir_modal
|
42
|
-
end
|
43
|
-
|
44
|
-
def buscar
|
45
|
-
pg_respond_buscar
|
46
|
-
end
|
47
|
-
|
48
|
-
def index
|
49
|
-
@collection = filtros_y_policy atributos_para_buscar
|
50
|
-
@collection = sort_collection(@collection)
|
51
|
-
pg_respond_index
|
52
|
-
end
|
53
|
-
|
54
|
-
def show
|
55
|
-
add_breadcrumb instancia_modelo, instancia_modelo.target_object
|
56
|
-
|
57
|
-
pg_respond_show
|
58
|
-
end
|
59
|
-
|
60
|
-
def new
|
61
|
-
add_breadcrumb "Crear #{@clase_modelo.nombre_singular.downcase}"
|
62
|
-
end
|
63
|
-
|
64
|
-
def edit
|
65
|
-
add_breadcrumb instancia_modelo, instancia_modelo.target_object
|
66
|
-
add_breadcrumb 'Editando'
|
67
|
-
end
|
68
|
-
|
69
|
-
def create
|
70
|
-
pg_respond_create
|
71
|
-
end
|
72
|
-
|
73
|
-
def update
|
74
|
-
pg_respond_update
|
75
|
-
end
|
76
|
-
|
77
|
-
def destroy
|
78
|
-
url = namespaced_path(@clase_modelo)
|
79
|
-
pg_respond_destroy(instancia_modelo, url)
|
80
|
-
end
|
81
|
-
|
82
|
-
# End public endpoints
|
83
|
-
|
84
37
|
def mobile_device?
|
85
38
|
request.user_agent =~ /Mobile|webOS/
|
86
39
|
end
|
87
40
|
|
88
|
-
helper_method :any_filter?
|
89
|
-
|
90
|
-
def any_filter?
|
91
|
-
params.keys.reject { |a| a.in? %w[controller action page page_size order_by order_direction] }.any?
|
92
|
-
end
|
93
|
-
|
94
|
-
helper_method :current_page_size
|
95
|
-
|
96
|
-
def current_page_size
|
97
|
-
if params[:page_size].present?
|
98
|
-
session[:page_size] = params[:page_size]
|
99
|
-
params[:page_size].to_i
|
100
|
-
else
|
101
|
-
default_page_size
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def default_page_size
|
106
|
-
session[:page_size].present? ? session[:page_size].to_i : 10
|
107
|
-
end
|
108
|
-
|
109
41
|
protected
|
110
42
|
|
111
|
-
def pg_respond_update(object: nil)
|
112
|
-
object ||= instancia_modelo
|
113
|
-
respond_to do |format|
|
114
|
-
if (@saved = object.save)
|
115
|
-
format.html { redirect_to object.decorate.target_object }
|
116
|
-
format.json { render json: object.decorate }
|
117
|
-
else
|
118
|
-
format.html { render :edit, status: :unprocessable_entity }
|
119
|
-
format.json { render json: object.errors, status: :unprocessable_entity }
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def pg_respond_create(object: nil)
|
125
|
-
object ||= instancia_modelo
|
126
|
-
respond_to do |format|
|
127
|
-
if (@saved = object.save)
|
128
|
-
if params[:asociable]
|
129
|
-
format.turbo_stream do
|
130
|
-
render turbo_stream:
|
131
|
-
turbo_stream.update('pg-associable-form', <<~HTML
|
132
|
-
<div data-modal-target="response" data-response='#{object.decorate.to_json}'></div>
|
133
|
-
HTML
|
134
|
-
)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
format.html do
|
138
|
-
if params[:save_and_next] == 'true'
|
139
|
-
new_path = "#{url_for(@clase_modelo)}/new"
|
140
|
-
redirect_to new_path, notice: "#{@clase_modelo.nombre_singular} creado."
|
141
|
-
else
|
142
|
-
redirect_to object.decorate.target_object
|
143
|
-
end
|
144
|
-
end
|
145
|
-
format.json { render json: object.decorate }
|
146
|
-
else
|
147
|
-
if params[:asociable]
|
148
|
-
format.turbo_stream do
|
149
|
-
render turbo_stream:
|
150
|
-
turbo_stream.update('pg-associable-form', partial: 'form', locals: { asociable: true })
|
151
|
-
end
|
152
|
-
end
|
153
|
-
format.html { render :new, status: :unprocessable_entity }
|
154
|
-
format.json { render json: object.errors.full_messages, status: :unprocessable_entity }
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
def pg_respond_index
|
160
|
-
respond_to do |format|
|
161
|
-
format.json { render json: @collection }
|
162
|
-
format.html { render_listing }
|
163
|
-
format.xlsx do
|
164
|
-
render xlsx: 'download',
|
165
|
-
filename: "#{@clase_modelo.nombre_plural.gsub(' ', '-').downcase}" \
|
166
|
-
"-#{Time.zone.now.strftime('%Y-%m-%d-%H.%M.%S')}.xlsx"
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def pg_respond_show(object = nil)
|
172
|
-
respond_to do |format|
|
173
|
-
format.json { render json: object || instancia_modelo }
|
174
|
-
format.html
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def pg_respond_destroy(model, redirect_url = nil)
|
179
|
-
if destroy_model(model)
|
180
|
-
respond_to do |format|
|
181
|
-
format.html do
|
182
|
-
if redirect_url.present?
|
183
|
-
redirect_to redirect_url, notice: 'Elemento borrado.', status: :see_other
|
184
|
-
else
|
185
|
-
redirect_back(fallback_location: root_path, notice: 'Elemento borrado.', status: 303)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
format.json { head :no_content }
|
189
|
-
end
|
190
|
-
else
|
191
|
-
respond_to do |format|
|
192
|
-
format.html do
|
193
|
-
if model.respond_to?(:associated_elements) && model.associated_elements.present?
|
194
|
-
@model = model
|
195
|
-
render destroy_error_details_view
|
196
|
-
else
|
197
|
-
flash[:alert] = @error_message
|
198
|
-
# if redirect_url.present?
|
199
|
-
# redirect_to redirect_url
|
200
|
-
# else
|
201
|
-
redirect_back(fallback_location: root_path, status: 303)
|
202
|
-
# end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
format.json { render json: { error: @error_message }, status: :unprocessable_entity }
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
# TODO: crear esta vista en pg_rails
|
211
|
-
def destroy_error_details_view
|
212
|
-
'destroy_error_details'
|
213
|
-
end
|
214
|
-
|
215
|
-
def destroy_model(model)
|
216
|
-
@error_message = 'No se pudo eliminar el registro'
|
217
|
-
begin
|
218
|
-
destroy_method = model.respond_to?(:discard) ? :discard : :destroy
|
219
|
-
return true if model.send(destroy_method)
|
220
|
-
|
221
|
-
@error_message = model.errors.full_messages.join(', ')
|
222
|
-
false
|
223
|
-
rescue ActiveRecord::InvalidForeignKey => e
|
224
|
-
# class_name = /from table \"(?<table_name>[\p{L}_]*)\"/.match(e.message)[:table_name].singularize.camelcase
|
225
|
-
# # pk_id = /from table \"(?<pk_id>[\p{L}_]*)\"/.match(e.message)[:pk_id].singularize.camelcase
|
226
|
-
# clazz = Object.const_get class_name
|
227
|
-
# objects = clazz.where(model.class.table_name.singularize => model)
|
228
|
-
model_name = t("activerecord.models.#{model.class.name.underscore}")
|
229
|
-
@error_message = "#{model_name} no se pudo borrar porque tiene elementos asociados."
|
230
|
-
logger.debug e.message
|
231
|
-
end
|
232
|
-
false
|
233
|
-
end
|
234
|
-
|
235
|
-
def render_listing
|
236
|
-
@collection = @collection.page(params[:page]).per(current_page_size)
|
237
|
-
end
|
238
|
-
|
239
|
-
def buscar_instancia
|
240
|
-
if Object.const_defined?('FriendlyId') && @clase_modelo.is_a?(FriendlyId)
|
241
|
-
@clase_modelo.friendly.find(params[:id])
|
242
|
-
else
|
243
|
-
@clase_modelo.find(params[:id])
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
def set_instancia_modelo
|
248
|
-
if action_name.in? %w[new create]
|
249
|
-
self.instancia_modelo = @clase_modelo.new(modelo_params)
|
250
|
-
else
|
251
|
-
self.instancia_modelo = buscar_instancia
|
252
|
-
|
253
|
-
instancia_modelo.assign_attributes(modelo_params) if action_name.in? %w[update]
|
254
|
-
end
|
255
|
-
|
256
|
-
instancia_modelo.current_user = send(PgEngine.configuracion.current_user_method)
|
257
|
-
|
258
|
-
authorize instancia_modelo
|
259
|
-
|
260
|
-
# TODO: problema en create y update cuando falla la validacion
|
261
|
-
self.instancia_modelo = instancia_modelo.decorate if action_name.in? %w[show edit new]
|
262
|
-
end
|
263
|
-
|
264
|
-
def instancia_modelo=(val)
|
265
|
-
instance_variable_set(:"@#{nombre_modelo}", val)
|
266
|
-
end
|
267
|
-
|
268
|
-
def instancia_modelo
|
269
|
-
instance_variable_get(:"@#{nombre_modelo}")
|
270
|
-
end
|
271
|
-
|
272
|
-
def modelo_params
|
273
|
-
if action_name == 'new'
|
274
|
-
params.permit(atributos_permitidos)
|
275
|
-
else
|
276
|
-
params.require(nombre_modelo).permit(atributos_permitidos)
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
def nombre_modelo
|
281
|
-
@clase_modelo.name.underscore
|
282
|
-
end
|
283
|
-
|
284
43
|
def default_url_options(options = {})
|
285
44
|
if Rails.env.production?
|
286
45
|
options.merge(protocol: 'https')
|
@@ -289,48 +48,6 @@ module PgEngine
|
|
289
48
|
end
|
290
49
|
end
|
291
50
|
|
292
|
-
def clase_modelo
|
293
|
-
# agarro la variable o intento con el nombre del controller
|
294
|
-
@clase_modelo ||= self.class.name.singularize.gsub('Controller', '').constantize
|
295
|
-
end
|
296
|
-
|
297
|
-
def filtros_y_policy(campos)
|
298
|
-
@filtros = PgEngine::FiltrosBuilder.new(
|
299
|
-
self, clase_modelo, campos
|
300
|
-
)
|
301
|
-
scope = policy_scope(clase_modelo)
|
302
|
-
|
303
|
-
@filtros.filtrar(scope)
|
304
|
-
end
|
305
|
-
|
306
|
-
def do_sort(scope, field, direction)
|
307
|
-
unless scope.model.column_names.include? field.to_s
|
308
|
-
Utils::Logueador.warning("No existe el campo \"#{field}\"")
|
309
|
-
return scope
|
310
|
-
end
|
311
|
-
scope = scope.order(field => direction)
|
312
|
-
instance_variable_set(:@field, field)
|
313
|
-
instance_variable_set(:@direction, direction)
|
314
|
-
scope
|
315
|
-
rescue ArgumentError => e
|
316
|
-
Utils::Logueador.warning(e.to_s)
|
317
|
-
scope
|
318
|
-
end
|
319
|
-
|
320
|
-
def sort_collection(scope, options = {})
|
321
|
-
if params[:order_by].present?
|
322
|
-
field = params[:order_by]
|
323
|
-
direction = params[:order_direction]
|
324
|
-
do_sort(scope, field, direction)
|
325
|
-
elsif options[:default].present?
|
326
|
-
field = options[:default].first[0]
|
327
|
-
direction = options[:default].first[1]
|
328
|
-
do_sort(scope, field, direction)
|
329
|
-
else
|
330
|
-
scope
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
51
|
def fecha_invalida
|
335
52
|
respond_to do |format|
|
336
53
|
format.json do
|