mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-30 00:45:28 +08:00
Implement metadata model concern [SCI-11774]
This commit is contained in:
parent
a274ffce7e
commit
65b94afafa
3 changed files with 79 additions and 0 deletions
22
app/models/concerns/metadata_model.rb
Normal file
22
app/models/concerns/metadata_model.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module MetadataModel
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :with_metadata_value, lambda { |key, value|
|
||||
# sanitize key, replace . with -> and replace last -> with ->> to ensure string comparison at last level
|
||||
db_key =
|
||||
"metadata->#{key.to_s.split('.').map { |k| "'#{k.parameterize(separator: '_')}'" }.join('->')}".sub(/->(?!.*->)/, '->>')
|
||||
where("#{db_key} = ?", value.to_s)
|
||||
}
|
||||
|
||||
before_save :sanitize_metadata_keys!
|
||||
|
||||
def sanitize_metadata_keys!
|
||||
return unless metadata
|
||||
|
||||
self.metadata = metadata.deep_transform_keys { |k| k.parameterize(separator: '_') }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,6 +11,7 @@ class Project < ApplicationRecord
|
|||
include ViewableModel
|
||||
include PermissionCheckableModel
|
||||
include Assignable
|
||||
include MetadataModel
|
||||
|
||||
enum visibility: { hidden: 0, visible: 1 }
|
||||
|
||||
|
|
56
spec/models/concerns/metadata_model_spec.rb
Normal file
56
spec/models/concerns/metadata_model_spec.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe MetadataModel, type: :concern do
|
||||
let!(:user) { create :user }
|
||||
let!(:team) { create :team, created_by: user }
|
||||
|
||||
let!(:project_1) do
|
||||
Project.create!(
|
||||
name: 'Project 1',
|
||||
team: user.teams.first,
|
||||
created_by: user,
|
||||
metadata: {
|
||||
status: 'processed',
|
||||
info: {
|
||||
tag: 'important',
|
||||
number: 2
|
||||
}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
let!(:project_2) do
|
||||
Project.create!(
|
||||
name: 'Project 2',
|
||||
team: user.teams.first,
|
||||
created_by: user,
|
||||
metadata: {
|
||||
status: 'failed'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it '#with_metadata_value finds the correct project by metadata value' do
|
||||
results = Project.with_metadata_value(:status, 'processed')
|
||||
expect(results.count).to eq 1
|
||||
expect(results.last.id).to eq project_1.id
|
||||
end
|
||||
|
||||
it '#with_metadata_value finds the correct project by nested metadata value' do
|
||||
results = Project.with_metadata_value('info.tag', 'important')
|
||||
expect(results.count).to eq 1
|
||||
expect(results.last.id).to eq project_1.id
|
||||
|
||||
results = Project.with_metadata_value('info.number', 2)
|
||||
expect(results.count).to eq 1
|
||||
expect(results.last.id).to eq project_1.id
|
||||
end
|
||||
|
||||
it '#with_metadata_value escapes key input' do
|
||||
results = nil
|
||||
expect { results = Project.with_metadata_value("project'->>'tag' = \'one\') AND name", nil) }.to_not raise_error
|
||||
expect(results.count).to eq 0
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue