rails_com 1.2.5 → 1.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/rails_com/application.js +11 -27
- data/app/assets/javascripts/rails_com/attachment.js +24 -19
- data/app/assets/javascripts/rails_com/fetch_xhr_script.js +13 -2
- data/app/assets/javascripts/rails_com/footer.js +7 -1
- data/app/assets/javascripts/rails_com/picture.js +1 -0
- data/app/assets/javascripts/rails_com/time_local.js +10 -0
- data/app/controllers/active_storage_ext/admin/blob_defaults_controller.rb +2 -1
- data/app/controllers/concerns/rails_common_api.rb +25 -15
- data/app/controllers/concerns/rails_common_controller.rb +46 -0
- data/app/helpers/rails_com/assets_helper.rb +32 -14
- data/app/models/active_storage/blob_default.rb +19 -0
- data/app/views/active_storage_ext/admin/blob_defaults/_form.html.erb +1 -0
- data/app/views/active_storage_ext/admin/blob_defaults/index.html.erb +3 -2
- data/app/views/active_storage_ext/attachments/_default_image_item.html.erb +9 -1
- data/app/views/active_storage_ext/attachments/_list_edit.html.erb +11 -9
- data/app/views/active_storage_ext/attachments/_list_field.html.erb +6 -0
- data/db/migrate/20181012025833_rails_com_init.rb +1 -0
- data/lib/active_record/type/i18n.rb +19 -0
- data/lib/rails_com.rb +11 -21
- data/lib/rails_com/action_controller.rb +3 -0
- data/lib/rails_com/{helpers → action_controller}/controller_helper.rb +8 -9
- data/lib/rails_com/{rails_ext → action_controller}/errors.rb +0 -0
- data/lib/rails_com/action_controller/parameters.rb +16 -0
- data/lib/rails_com/action_view.rb +2 -0
- data/lib/rails_com/{rails_ext → action_view}/template_renderer.rb +5 -17
- data/lib/rails_com/{rails_ext → action_view}/translation_helper.rb +3 -1
- data/lib/rails_com/active_record.rb +3 -0
- data/lib/rails_com/{helpers → active_record}/model_helper.rb +0 -0
- data/lib/rails_com/{rails_ext → active_record}/persistence_sneakily.rb +0 -0
- data/lib/rails_com/active_record/translation.rb +66 -0
- data/lib/rails_com/active_storage.rb +4 -0
- data/lib/rails_com/{rails_ext → active_storage}/activestorage_attached.rb +1 -0
- data/lib/rails_com/active_storage/attached_macros.rb +20 -0
- data/lib/rails_com/{rails_ext → active_storage}/attachment_transfer.rb +4 -2
- data/lib/rails_com/active_storage/blob_ext.rb +34 -0
- data/lib/rails_com/{rails_ext → active_storage}/video_response.rb +2 -1
- data/lib/rails_com/core.rb +7 -0
- data/lib/rails_com/{core_ext → core}/array.rb +0 -0
- data/lib/rails_com/{core_ext → core}/date.rb +0 -0
- data/lib/rails_com/{core_ext → core}/hash.rb +0 -0
- data/lib/rails_com/{core_ext → core}/nil.rb +0 -0
- data/lib/rails_com/{core_ext → core}/numeric.rb +0 -0
- data/lib/rails_com/{core_ext → core}/string.rb +0 -0
- data/lib/rails_com/engine.rb +9 -4
- data/lib/rails_com/{rails_ext → generators}/named_base.rb +0 -0
- data/lib/rails_com/{rails_ext → generators}/scaffold_generator.rb +2 -2
- data/lib/rails_com/utils/uid_helper.rb +7 -1
- data/lib/rails_com/version.rb +1 -1
- data/lib/templates/erb/scaffold/{_search_form.html.erb.tt → _filter.html.erb.tt} +3 -0
- data/lib/templates/erb/scaffold/index.html.erb.tt +2 -4
- metadata +54 -23
- data/app/views/active_storage_ext/attachments/_list_form.html.erb +0 -28
- data/lib/rails_com/rails_ext/attached_macros.rb +0 -21
@@ -2,4 +2,23 @@ class ActiveStorage::BlobDefault < ApplicationRecord
|
|
2
2
|
self.table_name = 'active_storage_blob_defaults'
|
3
3
|
has_one_attached :file
|
4
4
|
|
5
|
+
after_commit :delete_private_cache, :delete_default_cache, on: [:create, :destroy]
|
6
|
+
after_update_commit :delete_private_cache, if: -> { saved_change_to_private? }
|
7
|
+
|
8
|
+
def delete_private_cache
|
9
|
+
Rails.cache.delete('blob_default/private')
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete_default_cache
|
13
|
+
Rails.cache.delete('blob_default/default')
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.defaults
|
17
|
+
Rails.cache.fetch('blob_default/default') do
|
18
|
+
ActiveStorage::BlobDefault.all.map do |i|
|
19
|
+
["#{i.record_class}_#{i.name}", i.file.blob_id]
|
20
|
+
end.to_h
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
5
24
|
end
|
@@ -18,7 +18,7 @@
|
|
18
18
|
<th><%= ActiveStorage::BlobDefault.human_attribute_name(:record_class) %></th>
|
19
19
|
<th><%= ActiveStorage::BlobDefault.human_attribute_name(:name) %></th>
|
20
20
|
<th><%= ActiveStorage::BlobDefault.human_attribute_name(:file) %></th>
|
21
|
-
<th
|
21
|
+
<th><%= ActiveStorage::BlobDefault.human_attribute_name(:private) %></th>
|
22
22
|
<th>Actions</th>
|
23
23
|
</tr>
|
24
24
|
</thead>
|
@@ -28,10 +28,11 @@
|
|
28
28
|
<td><%= blob_default.id %></td>
|
29
29
|
<td><%= blob_default.record_class %></td>
|
30
30
|
<td><%= blob_default.name %></td>
|
31
|
-
<td><%= blob_default.file_blob.key if blob_default.file_blob %></td>
|
32
31
|
<td>
|
32
|
+
<%= blob_default.file_blob.key if blob_default.file_blob %>
|
33
33
|
<%= render 'active_storage_ext/attachments/list', target: blob_default.file %>
|
34
34
|
</td>
|
35
|
+
<td><%= blob_default.private %></td>
|
35
36
|
<td class="ui labels">
|
36
37
|
<%= link_to edit_rails_ext_blob_default_path(blob_default), data: { tooltip: t('.edit') }, class: 'ui pink mini icon button' do %>
|
37
38
|
<i class="pencil alternate icon"></i>
|
@@ -1,4 +1,12 @@
|
|
1
|
-
<div class="ui image">
|
1
|
+
<div class="ui image attached">
|
2
|
+
<div class="ui placeholder">
|
3
|
+
<div class="image" style="text-align: center;line-height: 100px;">
|
4
|
+
<i class="plus icon"></i>
|
5
|
+
</div>
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div class="ui image" id="file_template" style="display: none;">
|
2
10
|
<a href="javascript:void(0);" onclick="this.parentNode.remove()" class="ui grey right corner mini label">
|
3
11
|
<i class="times icon"></i>
|
4
12
|
</a>
|
@@ -1,25 +1,27 @@
|
|
1
1
|
<% if target.is_a?(ActiveStorage::Attached::One) && target.attached? %>
|
2
2
|
<% if target.content_type.to_s.start_with?('image') %>
|
3
|
-
<%= render partial: '
|
3
|
+
<%= render partial: 'active_storage_ext/attachments/image_item', locals: { image: target } %>
|
4
4
|
<% elsif target.content_type.to_s.start_with?('video') %>
|
5
|
-
<%= render partial: '
|
5
|
+
<%= render partial: 'active_storage_ext/attachments/video_item', locals: { video: target } %>
|
6
6
|
<% else %>
|
7
7
|
<p id="attachment_<%= target.id %>">
|
8
|
-
<%= link_to target.filename,
|
9
|
-
<%= link_to 'x',
|
8
|
+
<%= link_to target.filename, rails_ext_blob_path(target) %>
|
9
|
+
<%= link_to 'x', rails_ext_attachment_path(target.id), method: :delete, data: { confirm: 'Are you sure?' }, remote: true %>
|
10
10
|
</p>
|
11
11
|
<% end %>
|
12
|
-
<% elsif target.is_a?(ActiveStorage::Attached::Many) %>
|
12
|
+
<% elsif target.is_a?(ActiveStorage::Attached::Many) && target.attached? %>
|
13
13
|
<% target.each do |file| %>
|
14
14
|
<% if file.content_type.to_s.start_with?('image') %>
|
15
|
-
<%= render partial: '
|
15
|
+
<%= render partial: 'active_storage_ext/attachments/image_item', locals: { image: file } %>
|
16
16
|
<% elsif file.content_type.to_s.start_with?('video') %>
|
17
|
-
<%= render partial: '
|
17
|
+
<%= render partial: 'active_storage_ext/attachments/video_item', locals: { video: file } %>
|
18
18
|
<% else %>
|
19
19
|
<p id="attachment_<%= file.id %>">
|
20
|
-
<%= link_to file.filename,
|
21
|
-
<%= link_to 'x',
|
20
|
+
<%= link_to file.filename, rails_ext_blob_path(file) %>
|
21
|
+
<%= link_to 'x', rails_ext_attachment_path(file.id), method: :delete, data: { confirm: 'Are you sure?' }, remote: true %>
|
22
22
|
</p>
|
23
23
|
<% end %>
|
24
24
|
<% end %>
|
25
|
+
<% else %>
|
26
|
+
<%= render partial: 'active_storage_ext/attachments/default_image_item' %>
|
25
27
|
<% end %>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<div class="top attached inline fields" id="<%= "#{target.record.class.name.underscore}_attachments_#{target.record.id}" %>">
|
2
|
+
<div class="six wide field"></div>
|
3
|
+
<div class="field ui tiny images" id="file_preview" data-controller="picture">
|
4
|
+
<%= render partial: 'active_storage_ext/attachments/list_edit', locals: { target: target } %>
|
5
|
+
</div>
|
6
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveRecord::Type
|
2
|
+
class I18n < Json
|
3
|
+
|
4
|
+
def type
|
5
|
+
:i18n
|
6
|
+
end
|
7
|
+
|
8
|
+
def deserialize(value)
|
9
|
+
if super && super.respond_to?(:[])
|
10
|
+
super[::I18n.locale.to_s]
|
11
|
+
else
|
12
|
+
value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
ActiveRecord::Type.register(:i18n, ActiveRecord::Type::I18n)
|
data/lib/rails_com.rb
CHANGED
@@ -2,33 +2,23 @@ require 'rails_com/version'
|
|
2
2
|
require 'rails_com/engine'
|
3
3
|
require 'rails_com/config'
|
4
4
|
|
5
|
+
require 'rails_com/core'
|
6
|
+
require 'rails_com/action_controller'
|
7
|
+
require 'rails_com/action_view'
|
8
|
+
require 'rails_com/active_record'
|
9
|
+
|
10
|
+
require 'rails_com/active_storage/blob_ext'
|
11
|
+
|
5
12
|
# Meta for Rails
|
6
13
|
require 'rails_com/meta/routes'
|
7
14
|
require 'rails_com/meta/models'
|
8
15
|
require 'rails_com/meta/controllers'
|
9
16
|
|
10
|
-
# Rails Helper
|
11
|
-
require 'rails_com/helpers/model_helper'
|
12
|
-
require 'rails_com/helpers/controller_helper'
|
13
|
-
|
14
|
-
# Ruby core extension
|
15
|
-
require 'rails_com/core_ext/hash'
|
16
|
-
require 'rails_com/core_ext/nil'
|
17
|
-
require 'rails_com/core_ext/array'
|
18
|
-
require 'rails_com/core_ext/date'
|
19
|
-
require 'rails_com/core_ext/numeric'
|
20
|
-
require 'rails_com/core_ext/string'
|
21
|
-
|
22
17
|
# Rails extension
|
23
|
-
require 'rails_com/
|
24
|
-
require 'rails_com/
|
25
|
-
|
26
|
-
|
27
|
-
require 'rails_com/rails_ext/persistence_sneakily'
|
28
|
-
require 'rails_com/rails_ext/translation_helper'
|
29
|
-
require 'rails_com/rails_ext/video_response'
|
30
|
-
require 'rails_com/rails_ext/attachment_transfer'
|
31
|
-
require 'rails_com/rails_ext/errors'
|
18
|
+
require 'rails_com/generators/named_base'
|
19
|
+
require 'rails_com/generators/scaffold_generator'
|
20
|
+
|
21
|
+
# controllers
|
32
22
|
require 'rails_com/sprockets/non_digest_assets'
|
33
23
|
|
34
24
|
# Utils
|
@@ -1,13 +1,5 @@
|
|
1
1
|
module RailsCom::ControllerHelper
|
2
2
|
|
3
|
-
def set_locale
|
4
|
-
if params[:locale]
|
5
|
-
session[:locale] = params[:locale]
|
6
|
-
end
|
7
|
-
|
8
|
-
I18n.locale = session[:locale] || I18n.default_locale
|
9
|
-
end
|
10
|
-
|
11
3
|
def detect_filter(filter)
|
12
4
|
callback = self.__callbacks[:process_action].find { |i| i.filter == filter.to_sym }
|
13
5
|
return false unless callback
|
@@ -25,6 +17,13 @@ module RailsCom::ControllerHelper
|
|
25
17
|
|
26
18
|
end
|
27
19
|
|
28
|
-
|
20
|
+
module RailsCom::FilterHelper
|
21
|
+
def whether_filter(filter)
|
22
|
+
self.get_callbacks(:process_action).map(&:filter).include?(filter.to_sym)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
ActiveSupport.on_load :action_controller do
|
29
27
|
include RailsCom::ControllerHelper
|
28
|
+
extend RailsCom::FilterHelper
|
30
29
|
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module RailsCom::Parameters
|
2
|
+
|
3
|
+
def require(key)
|
4
|
+
begin
|
5
|
+
super
|
6
|
+
ensure
|
7
|
+
@required_params ||= []
|
8
|
+
@required_params << key
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
ActiveSupport.on_load :action_controller_base do
|
15
|
+
ActionController::Parameters.prepend RailsCom::Parameters
|
16
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module RailsCom
|
2
2
|
|
3
3
|
module TemplateRenderer
|
4
4
|
|
@@ -34,21 +34,9 @@ module RailsExt
|
|
34
34
|
|
35
35
|
end
|
36
36
|
|
37
|
-
module Parameters
|
38
|
-
|
39
|
-
def require(key)
|
40
|
-
begin
|
41
|
-
super
|
42
|
-
ensure
|
43
|
-
@required_params ||= []
|
44
|
-
@required_params << key
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
37
|
end
|
51
38
|
|
52
|
-
|
53
|
-
ActionView::
|
54
|
-
|
39
|
+
ActiveSupport.on_load :action_view do
|
40
|
+
ActionView::TemplateRenderer.prepend RailsCom::TemplateRenderer
|
41
|
+
ActionView::PartialRenderer.prepend RailsCom::PartialRenderer
|
42
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module RailsCom::I18n
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
before_update :update_i18n_column
|
6
|
+
end
|
7
|
+
|
8
|
+
def update_i18n_column
|
9
|
+
str = []
|
10
|
+
self.changes.slice(*i18n_attributes).each do |key, _|
|
11
|
+
value = self.public_send("#{key}_before_type_cast")
|
12
|
+
str << "#{key} = #{key}::jsonb || '#{value.to_json}'::jsonb"
|
13
|
+
end
|
14
|
+
return if str.blank?
|
15
|
+
s = str.join(', ')
|
16
|
+
self.class.connection.execute "UPDATE #{self.class.table_name} SET #{s} WHERE id = #{self.id}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes_with_values_for_create(attribute_names)
|
20
|
+
r = super
|
21
|
+
r.slice(*i18n_attributes).each do |key, v|
|
22
|
+
r[key] = public_send "#{key}_before_type_cast"
|
23
|
+
end
|
24
|
+
r
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
module RailsCom::Translation
|
30
|
+
|
31
|
+
# name
|
32
|
+
# * store as jsonb in database;
|
33
|
+
# * read with i18n scope
|
34
|
+
def has_translations(*columns)
|
35
|
+
mattr_accessor :i18n_attributes
|
36
|
+
self.i18n_attributes = columns.map(&:to_s)
|
37
|
+
include RailsCom::I18n
|
38
|
+
columns.each do |column|
|
39
|
+
attribute column, :i18n
|
40
|
+
|
41
|
+
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
42
|
+
|
43
|
+
def #{column}=(value)
|
44
|
+
if value.is_a?(String)
|
45
|
+
super(::I18n.locale.to_s => value)
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
RUBY_EVAL
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def _update_record(values, constraints)
|
57
|
+
mattr_accessor :i18n_attributes
|
58
|
+
values.except!(*i18n_attributes)
|
59
|
+
super
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
ActiveSupport.on_load :active_record do
|
65
|
+
extend RailsCom::Translation
|
66
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RailsCom::AttachedOne
|
2
|
+
|
3
|
+
def attachment
|
4
|
+
if super
|
5
|
+
return super
|
6
|
+
elsif defined?(@attachment)
|
7
|
+
return @attachment
|
8
|
+
end
|
9
|
+
|
10
|
+
id = ActiveStorage::BlobDefault.defaults["#{record.class.name}_#{name}"]
|
11
|
+
@attachment = build_attachment(blob: ActiveStorage::Blob.find(id)) if id
|
12
|
+
end
|
13
|
+
|
14
|
+
def attached?
|
15
|
+
attachment&.id?
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
ActiveStorage::Attached::One.prepend RailsCom::AttachedOne
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'active_storage/downloading'
|
2
|
-
module AttachmentTransfer
|
2
|
+
module RailsCom::AttachmentTransfer
|
3
3
|
include ActiveStorage::Downloading
|
4
4
|
|
5
5
|
def copy
|
@@ -39,4 +39,6 @@ module AttachmentTransfer
|
|
39
39
|
ActiveStorage.paths[:ffmpeg] || 'ffmpeg'
|
40
40
|
end
|
41
41
|
|
42
|
-
end
|
42
|
+
end
|
43
|
+
|
44
|
+
ActiveStorage::Attachment.include RailsCom::AttachmentTransfer
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RailsCom::BlobExt
|
2
|
+
|
3
|
+
def self.prepended(klass)
|
4
|
+
klass.class_attribute :private_service
|
5
|
+
end
|
6
|
+
|
7
|
+
def duration
|
8
|
+
r = metadata[:duration] || 0
|
9
|
+
rh = TimeHelper.exact_distance_time(r.to_f)
|
10
|
+
"#{rh[:minute]}:#{rh[:second].to_s.rjust(2, '0')}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def service
|
14
|
+
if private && private_service
|
15
|
+
private_service
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def private
|
22
|
+
return @private if defined?(@private)
|
23
|
+
rts = self.attachments.pluck(:record_type, :name).uniq.to_combined_h
|
24
|
+
ps = Rails.cache.fetch('blob_default/private') do
|
25
|
+
ActiveStorage::BlobDefault.where(private: true).pluck(:record_class, :name).to_combined_h
|
26
|
+
end
|
27
|
+
@private = ps.slice(*rts.keys).map { |p, v| (Array(rts[p]) - Array(v)).blank? }.uniq == [true]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
ActiveSupport.on_load(:active_storage_blob) do
|
33
|
+
prepend RailsCom::BlobExt
|
34
|
+
end
|