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.
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