Skip to content

Commit b8b44ac

Browse files
committed
Fix filtering Attachments by only or except param
This has been broken for a long time now. Signed-off-by: Thomas von Deyen <vondeyen@blish.cloud>
1 parent f619b5f commit b8b44ac

File tree

9 files changed

+133
-14
lines changed

9 files changed

+133
-14
lines changed

app/controllers/alchemy/admin/attachments_controller.rb

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,22 @@ def default_sort_order
7272
end
7373

7474
def search_filter_params
75-
@_search_filter_params ||= params.except(*COMMON_SEARCH_FILTER_EXCLUDES + [:attachment]).permit(
76-
*common_search_filter_includes + [
77-
:form_field_id
78-
]
79-
)
75+
@_search_filter_params ||= begin
76+
params[:q] ||= ActionController::Parameters.new
77+
params.except(*COMMON_SEARCH_FILTER_EXCLUDES + [:attachment]).permit(
78+
*common_search_filter_includes + [
79+
:form_field_id
80+
]
81+
)
82+
end
83+
end
84+
85+
def permitted_ransack_search_fields
86+
super + [
87+
{by_file_type: []},
88+
:not_file_type,
89+
{not_file_type: []}
90+
]
8091
end
8192

8293
def handle_uploader_response(status:)

app/models/alchemy/attachment.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ class Attachment < BaseRecord
2929

3030
stampable stamper_class_name: Alchemy.user_class_name
3131

32-
scope :by_file_type, ->(file_type) do
32+
scope :by_file_type, ->(*file_type) do
3333
Alchemy.storage_adapter.by_file_type_scope(file_type)
3434
end
3535

36+
scope :not_file_type, ->(*file_type) do
37+
Alchemy.storage_adapter.not_file_type_scope(file_type)
38+
end
39+
3640
scope :recent, -> { where("#{table_name}.created_at > ?", Time.current - 24.hours).order(:created_at) }
3741
scope :without_tag, -> { left_outer_joins(:taggings).where(gutentag_taggings: {id: nil}) }
3842

@@ -79,7 +83,7 @@ def allowed_filetypes
7983
end
8084

8185
def ransackable_scopes(_auth_object = nil)
82-
%i[by_file_type recent last_upload without_tag deletable]
86+
%i[by_file_type not_file_type recent last_upload without_tag deletable]
8387
end
8488
end
8589

app/models/alchemy/storage_adapter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class UnknownAdapterError < StandardError; end
88
:attachment_url_class,
99
:by_file_format_scope,
1010
:by_file_type_scope,
11+
:not_file_type_scope,
1112
:file_extension,
1213
:file_formats,
1314
:file_mime_type,

app/models/alchemy/storage_adapter/active_storage.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,24 @@ def rescuable_errors
8080
::ActiveStorage::Error
8181
end
8282

83-
# @param [String]
83+
# @param [String, Array<String>]
8484
# @return [Alchemy::Picture::ActiveRecord_Relation]
8585
def by_file_format_scope(file_format)
8686
Picture.with_attached_image_file.joins(:image_file_blob).where(active_storage_blobs: {content_type: file_format})
8787
end
8888

89-
# @param [String]
89+
# @param [String, Array<String>]
9090
# @return [Alchemy::Atachment::ActiveRecord_Relation]
9191
def by_file_type_scope(file_type)
9292
Attachment.with_attached_file.joins(:file_blob).where(active_storage_blobs: {content_type: file_type})
9393
end
9494

95+
# @param [String, Array<String>]
96+
# @return [Alchemy::Atachment::ActiveRecord_Relation]
97+
def not_file_type_scope(file_type)
98+
Attachment.with_attached_file.joins(:file_blob).where.not(active_storage_blobs: {content_type: file_type})
99+
end
100+
95101
# @param [Alchemy::Attachment]
96102
# @return [String]
97103
def file_name(attachment)

app/models/alchemy/storage_adapter/dragonfly.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,24 @@ def rescuable_errors
103103
::Dragonfly::Job::Fetch::NotFound
104104
end
105105

106-
# @param [String]
106+
# @param [String, Array<String>]
107107
# @return [Alchemy::Picture::ActiveRecord_Relation]
108108
def by_file_format_scope(file_format)
109109
Picture.where(image_file_format: file_format)
110110
end
111111

112-
# @param [String]
112+
# @param [String, Array<String>]
113113
# @return [Alchemy::Attachment::ActiveRecord_Relation]
114114
def by_file_type_scope(file_type)
115115
Attachment.where(file_mime_type: file_type)
116116
end
117117

118+
# @param [String, Array<String>]
119+
# @return [Alchemy::Attachment::ActiveRecord_Relation]
120+
def not_file_type_scope(file_type)
121+
Attachment.where.not(file_mime_type: file_type)
122+
end
123+
118124
# @param [Alchemy::Attachment]
119125
# @return [String]
120126
def file_name(attachment)

app/views/alchemy/admin/attachments/_overlay_file_list.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<% if @attachments.empty? %>
22
<%= render_message do %>
3-
<% if search_filter_params[:q].present? %>
3+
<% if search_filter_params.present? %>
44
<%= Alchemy.t(:no_search_results) %>
55
<% else %>
66
<%= Alchemy.t(:no_files_in_archive) %>

app/views/alchemy/ingredients/_file_editor.html.erb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
<% dialog_link = link_to_dialog render_icon("file-add"),
22
alchemy.admin_attachments_path(
33
form_field_id: file_editor.form_field_id(:attachment_id),
4-
only: file_editor.settings[:only],
5-
except: file_editor.settings[:except]
4+
q: {
5+
by_file_type: Array.wrap(file_editor.settings[:only]).map { |ext|
6+
Marcel::MimeType.for(
7+
extension: ext
8+
)
9+
},
10+
not_file_type: Array.wrap(file_editor.settings[:except]).map { |ext|
11+
Marcel::MimeType.for(
12+
extension: ext
13+
)
14+
}
15+
}
616
),
717
{
818
title: Alchemy.t(:assign_file),

spec/controllers/alchemy/admin/attachments_controller_spec.rb

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,81 @@ module Alchemy
4646
get :index
4747
end
4848

49+
context "when params[:only] is set" do
50+
let(:pdf_file) { fixture_file_upload("file.pdf") }
51+
52+
let!(:pdf_attachment) { create(:alchemy_attachment, name: "PDF", file: pdf_file) }
53+
54+
context "to single extension" do
55+
it "should filter attachments by file type from extension" do
56+
attachment
57+
get :index, params: {only: "pdf"}
58+
expect(assigns(:attachments)).to contain_exactly(pdf_attachment)
59+
end
60+
end
61+
62+
context "to multiple extensions" do
63+
let(:gif_file) { fixture_file_upload("animated.gif") }
64+
65+
let!(:gif_attachment) { create(:alchemy_attachment, name: "GIF", file: gif_file) }
66+
67+
it "should filter attachments by file type from extension" do
68+
attachment
69+
get :index, params: {only: ["pdf", "gif"]}
70+
expect(assigns(:attachments)).to contain_exactly(pdf_attachment, gif_attachment)
71+
end
72+
end
73+
end
74+
75+
context "when params[:except] is set" do
76+
let(:pdf_file) { fixture_file_upload("file.pdf") }
77+
78+
let!(:pdf_attachment) { create(:alchemy_attachment, name: "PDF", file: pdf_file) }
79+
80+
context "to single extension" do
81+
it "should filter attachments by file type from extension" do
82+
get :index, params: {except: "pdf"}
83+
expect(assigns(:attachments)).to contain_exactly(attachment)
84+
end
85+
end
86+
87+
context "to multiple extensions" do
88+
let(:gif_file) { fixture_file_upload("animated.gif") }
89+
90+
let!(:gif_attachment) { create(:alchemy_attachment, name: "GIF", file: gif_file) }
91+
92+
it "should filter attachments by file type from extension" do
93+
get :index, params: {except: ["pdf", "gif"]}
94+
expect(assigns(:attachments)).to contain_exactly(attachment)
95+
end
96+
end
97+
end
98+
99+
context "when params[:except] and params[:only] are set" do
100+
let(:pdf_file) { fixture_file_upload("file.pdf") }
101+
102+
let!(:pdf_attachment) { create(:alchemy_attachment, name: "PDF", file: pdf_file) }
103+
104+
context "to single extension" do
105+
it "should filter records by file type from extension" do
106+
attachment
107+
get :index, params: {except: "png", only: "pdf"}
108+
expect(assigns(:attachments)).to contain_exactly(pdf_attachment)
109+
end
110+
end
111+
112+
context "to multiple extensions" do
113+
let(:gif_file) { fixture_file_upload("animated.gif") }
114+
115+
let!(:gif_attachment) { create(:alchemy_attachment, name: "GIF", file: gif_file) }
116+
117+
it "should filter records by file type from extension" do
118+
get :index, params: {except: ["pdf", "gif"]}
119+
expect(assigns(:attachments)).to contain_exactly(attachment)
120+
end
121+
end
122+
end
123+
49124
context "when params[:tagged_with] is set" do
50125
it "should filter the records by tags" do
51126
expect(Attachment).to receive(:tagged_with).and_return(Attachment.all)

spec/dummy/config/alchemy/elements.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
ingredients:
6262
- role: file
6363
type: File
64+
settings:
65+
except: mp3
6466

6567
- name: bild
6668
ingredients:
@@ -171,9 +173,13 @@
171173
- role: audio
172174
type: Audio
173175
hint: true
176+
settings:
177+
only: [mp3, wav]
174178
- role: video
175179
type: Video
176180
hint: true
181+
settings:
182+
only: webm
177183
- role: page
178184
type: Page
179185
hint: true

0 commit comments

Comments
 (0)