rails_com 1.2.5 → 1.2.6

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/rails_com/application.js +11 -27
  3. data/app/assets/javascripts/rails_com/attachment.js +24 -19
  4. data/app/assets/javascripts/rails_com/fetch_xhr_script.js +13 -2
  5. data/app/assets/javascripts/rails_com/footer.js +7 -1
  6. data/app/assets/javascripts/rails_com/picture.js +1 -0
  7. data/app/assets/javascripts/rails_com/time_local.js +10 -0
  8. data/app/controllers/active_storage_ext/admin/blob_defaults_controller.rb +2 -1
  9. data/app/controllers/concerns/rails_common_api.rb +25 -15
  10. data/app/controllers/concerns/rails_common_controller.rb +46 -0
  11. data/app/helpers/rails_com/assets_helper.rb +32 -14
  12. data/app/models/active_storage/blob_default.rb +19 -0
  13. data/app/views/active_storage_ext/admin/blob_defaults/_form.html.erb +1 -0
  14. data/app/views/active_storage_ext/admin/blob_defaults/index.html.erb +3 -2
  15. data/app/views/active_storage_ext/attachments/_default_image_item.html.erb +9 -1
  16. data/app/views/active_storage_ext/attachments/_list_edit.html.erb +11 -9
  17. data/app/views/active_storage_ext/attachments/_list_field.html.erb +6 -0
  18. data/db/migrate/20181012025833_rails_com_init.rb +1 -0
  19. data/lib/active_record/type/i18n.rb +19 -0
  20. data/lib/rails_com.rb +11 -21
  21. data/lib/rails_com/action_controller.rb +3 -0
  22. data/lib/rails_com/{helpers → action_controller}/controller_helper.rb +8 -9
  23. data/lib/rails_com/{rails_ext → action_controller}/errors.rb +0 -0
  24. data/lib/rails_com/action_controller/parameters.rb +16 -0
  25. data/lib/rails_com/action_view.rb +2 -0
  26. data/lib/rails_com/{rails_ext → action_view}/template_renderer.rb +5 -17
  27. data/lib/rails_com/{rails_ext → action_view}/translation_helper.rb +3 -1
  28. data/lib/rails_com/active_record.rb +3 -0
  29. data/lib/rails_com/{helpers → active_record}/model_helper.rb +0 -0
  30. data/lib/rails_com/{rails_ext → active_record}/persistence_sneakily.rb +0 -0
  31. data/lib/rails_com/active_record/translation.rb +66 -0
  32. data/lib/rails_com/active_storage.rb +4 -0
  33. data/lib/rails_com/{rails_ext → active_storage}/activestorage_attached.rb +1 -0
  34. data/lib/rails_com/active_storage/attached_macros.rb +20 -0
  35. data/lib/rails_com/{rails_ext → active_storage}/attachment_transfer.rb +4 -2
  36. data/lib/rails_com/active_storage/blob_ext.rb +34 -0
  37. data/lib/rails_com/{rails_ext → active_storage}/video_response.rb +2 -1
  38. data/lib/rails_com/core.rb +7 -0
  39. data/lib/rails_com/{core_ext → core}/array.rb +0 -0
  40. data/lib/rails_com/{core_ext → core}/date.rb +0 -0
  41. data/lib/rails_com/{core_ext → core}/hash.rb +0 -0
  42. data/lib/rails_com/{core_ext → core}/nil.rb +0 -0
  43. data/lib/rails_com/{core_ext → core}/numeric.rb +0 -0
  44. data/lib/rails_com/{core_ext → core}/string.rb +0 -0
  45. data/lib/rails_com/engine.rb +9 -4
  46. data/lib/rails_com/{rails_ext → generators}/named_base.rb +0 -0
  47. data/lib/rails_com/{rails_ext → generators}/scaffold_generator.rb +2 -2
  48. data/lib/rails_com/utils/uid_helper.rb +7 -1
  49. data/lib/rails_com/version.rb +1 -1
  50. data/lib/templates/erb/scaffold/{_search_form.html.erb.tt → _filter.html.erb.tt} +3 -0
  51. data/lib/templates/erb/scaffold/index.html.erb.tt +2 -4
  52. metadata +54 -23
  53. data/app/views/active_storage_ext/attachments/_list_form.html.erb +0 -28
  54. 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
@@ -3,5 +3,6 @@
3
3
  <%= f.text_field :record_class %>
4
4
  <%= f.text_field :name %>
5
5
  <%= f.file_field :file %>
6
+ <%= f.check_box :private %>
6
7
  <%= f.submit %>
7
8
  <% 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></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: 'active_storage/attachments/image_item', locals: { image: target } %>
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: 'active_storage/attachments/video_item', locals: { video: target } %>
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, rails_blob_path(target) %>
9
- <%= link_to 'x', rails_attachment_path(target.id), method: :delete, data: {confirm: 'Are you sure?'}, remote: true %>
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: 'active_storage/attachments/image_item', locals: { image: file } %>
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: 'active_storage/attachments/video_item', locals: { video: file } %>
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, rails_blob_path(file) %>
21
- <%= link_to 'x', rails_attachment_path(file.id), method: :delete, data: {confirm: 'Are you sure?'}, remote: true %>
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>
@@ -4,6 +4,7 @@ class RailsComInit < ActiveRecord::Migration[5.2]
4
4
  create_table :active_storage_blob_defaults do |t|
5
5
  t.string :record_class
6
6
  t.string :name
7
+ t.boolean :private
7
8
  t.timestamps
8
9
  end
9
10
 
@@ -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)
@@ -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/rails_ext/template_renderer'
24
- require 'rails_com/rails_ext/scaffold_generator'
25
- require 'rails_com/rails_ext/named_base'
26
- require 'rails_com/rails_ext/activestorage_attached'
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
@@ -0,0 +1,3 @@
1
+ require_relative 'action_controller/controller_helper'
2
+ require_relative 'action_controller/errors'
3
+ require_relative 'action_controller/parameters'
@@ -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
- ActiveSupport.on_load :action_controller_base do
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
@@ -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
@@ -0,0 +1,2 @@
1
+ require_relative 'action_view/template_renderer'
2
+ require_relative 'action_view/translation_helper'
@@ -1,4 +1,4 @@
1
- module RailsExt
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
- ActionView::TemplateRenderer.prepend RailsExt::TemplateRenderer
53
- ActionView::PartialRenderer.prepend RailsExt::PartialRenderer
54
- ActionController::Parameters.prepend RailsExt::Parameters
39
+ ActiveSupport.on_load :action_view do
40
+ ActionView::TemplateRenderer.prepend RailsCom::TemplateRenderer
41
+ ActionView::PartialRenderer.prepend RailsCom::PartialRenderer
42
+ end
@@ -15,4 +15,6 @@ module RailsCom
15
15
  end
16
16
  end
17
17
 
18
- ActionView::Base.include RailsCom::TranslationHelper
18
+ ActiveSupport.on_load :action_view do
19
+ include RailsCom::TranslationHelper
20
+ end
@@ -0,0 +1,3 @@
1
+ require 'active_record/type/i18n'
2
+ require_relative 'active_record/translation'
3
+ require_relative 'active_record/model_helper'
@@ -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,4 @@
1
+ require_relative 'active_storage/activestorage_attached'
2
+ require_relative 'active_storage/attached_macros'
3
+ require_relative 'active_storage/attachment_transfer'
4
+ require_relative 'active_storage/video_response'
@@ -1,3 +1,4 @@
1
+ require 'httparty'
1
2
  module ActiveStorage
2
3
  class Attached
3
4
 
@@ -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