naranya_ecm-sdk 0.0.14 → 0.0.15
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.
- checksums.yaml +4 -4
- data/lib/naranya_ecm/behaviors/localizable.rb +27 -31
- data/lib/naranya_ecm/behaviors/mediable.rb +25 -0
- data/lib/naranya_ecm/behaviors/timestampable.rb +18 -15
- data/lib/naranya_ecm/cache/key.rb +32 -56
- data/lib/naranya_ecm/cache/methods.rb +50 -63
- data/lib/naranya_ecm/lifecycles/content_lifecycle.rb +39 -16
- data/lib/naranya_ecm/models/category.rb +11 -30
- data/lib/naranya_ecm/models/content.rb +73 -73
- data/lib/naranya_ecm/models/content_version.rb +50 -29
- data/lib/naranya_ecm/models/download_authorization.rb +22 -26
- data/lib/naranya_ecm/models/media_resource.rb +49 -15
- data/lib/naranya_ecm/rest/associations.rb +156 -0
- data/lib/naranya_ecm/rest/client.rb +4 -0
- data/lib/naranya_ecm/rest/errors.rb +53 -0
- data/lib/naranya_ecm/rest/finder_methods.rb +50 -0
- data/lib/naranya_ecm/rest/model.rb +215 -0
- data/lib/naranya_ecm/rest/persistence.rb +122 -0
- data/lib/naranya_ecm/rest/relation.rb +54 -0
- data/lib/naranya_ecm/search/hit.rb +19 -14
- data/lib/naranya_ecm/search/methods.rb +18 -20
- data/lib/naranya_ecm/search/query.rb +229 -230
- data/lib/naranya_ecm/search/results.rb +136 -139
- data/lib/naranya_ecm-sdk/version.rb +1 -1
- data/lib/naranya_ecm-sdk.rb +54 -13
- data/naranya_ecm-sdk.gemspec +1 -1
- data/spec/models/category_spec.rb +7 -2
- data/spec/models/content_spec.rb +11 -2
- data/spec/models/media_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/naranya_ecms_shared_specs.rb +0 -12
- metadata +15 -19
- data/lib/naranya_ecm/behaviors/resourceable.rb +0 -22
- data/lib/naranya_ecm/behaviors.rb +0 -10
- data/lib/naranya_ecm/cache.rb +0 -9
- data/lib/naranya_ecm/has_many_patch.rb +0 -105
- data/lib/naranya_ecm/lifecycles/lifecycleable.rb +0 -43
- data/lib/naranya_ecm/lifecycles/version_lifecycle.rb +0 -75
- data/lib/naranya_ecm/lifecycles.rb +0 -10
- data/lib/naranya_ecm/models/embedded_hash.rb +0 -10
- data/lib/naranya_ecm/models/embedded_localized_hash.rb +0 -38
- data/lib/naranya_ecm/models/lifecycle.rb +0 -34
- data/lib/naranya_ecm/models.rb +0 -15
- data/lib/naranya_ecm/search.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f6a90236bd794d754bdf445805afdf1b4539d4f
|
4
|
+
data.tar.gz: e40ad3616ae04fb8932e2df7fb47546efb0ce7b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0802bf180226d3b443697ab502f09e1b13a23dd79105b246419de9a8e534cdc4db8351b6577953551ad3e8361c3a67a61e35c896509266c2309affbb9458f3a
|
7
|
+
data.tar.gz: 62565940d9f2025491f2a5d30d45990e1a2744afa2b411feb8c0bd1ebb5b766a4bd92b87b0127a22e098e6619686379318762f725dcabc8f163f86443316fc9b
|
@@ -1,41 +1,37 @@
|
|
1
1
|
require 'active_support/concern'
|
2
2
|
|
3
|
-
module NaranyaEcm
|
3
|
+
module NaranyaEcm::Behaviors
|
4
|
+
module Localizable
|
4
5
|
|
5
|
-
|
6
|
-
module Localizable
|
6
|
+
extend ActiveSupport::Concern
|
7
7
|
|
8
|
-
|
8
|
+
included do
|
9
|
+
# Delegar el acceso tipo "Enumerable":
|
10
|
+
delegate :any?, to: :@attributes
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
# Re-establece el acceso tipo Hash:
|
13
|
+
delegate :[], to: :@attributes
|
14
|
+
delegate :[]=, to: :@attributes
|
15
|
+
self.site = "http://www.example.com"
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
self.site = "http://www.example.com"
|
18
|
-
|
19
|
-
attribute_name = self.name.demodulize.underscore[0..-("_translations".length+1)]
|
20
|
-
alias_method attribute_name.to_sym, :lookup
|
21
|
-
end
|
17
|
+
attribute_name = self.name.demodulize.underscore[0..-("_translations".length+1)]
|
18
|
+
alias_method attribute_name.to_sym, :lookup
|
19
|
+
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
lookup_result || @attributes.present? ? @attributes.first[1] : nil
|
21
|
+
def locales
|
22
|
+
@attributes.keys
|
23
|
+
end
|
24
|
+
alias_method :available_locales, :locales
|
25
|
+
|
26
|
+
def lookup
|
27
|
+
locale = ::I18n.locale
|
28
|
+
if ::I18n.respond_to?(:fallbacks)
|
29
|
+
lookup_result = @attributes[::I18n.fallbacks[locale].map(&:to_s).find{ |loc| @attributes.has_key?(loc) }]
|
30
|
+
else
|
31
|
+
lookup_result = @attributes[locale.to_s]
|
36
32
|
end
|
37
|
-
|
33
|
+
lookup_result || @attributes.present? ? @attributes.first[1] : nil
|
38
34
|
end
|
39
|
-
end
|
40
35
|
|
41
|
-
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module NaranyaEcm::Behaviors
|
2
|
+
module Mediable
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def find_media_by_role(role_name)
|
7
|
+
mr = self.media_resources.nil? ? [] : self.media_resources
|
8
|
+
mr.detect { |mr| mr.roles.include? role_name }
|
9
|
+
end
|
10
|
+
|
11
|
+
def find_media_url_by_role(role_name)
|
12
|
+
mr = self.find_media_by_role role_name
|
13
|
+
mr.present? ? mr.downloadable_url : nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def select_media_by_role(role_name)
|
17
|
+
self.media_resources.select { |mr| mr.roles.include? role_name }
|
18
|
+
end
|
19
|
+
|
20
|
+
def select_media_urls_by_role(role_name)
|
21
|
+
mr = self.select_media_by_role(role_name).map(&:downloadable_url)
|
22
|
+
mr.flatten.uniq
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,22 +1,25 @@
|
|
1
1
|
require 'active_support/concern'
|
2
|
-
module NaranyaEcm
|
3
|
-
module Behaviors
|
4
|
-
module Timestampable
|
5
2
|
|
6
|
-
|
3
|
+
module NaranyaEcm::Behaviors
|
4
|
+
module Timestampable
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
[:created_at, :updated_at].each do |timestamp_name|
|
10
|
+
attr_accessor timestamp_name
|
11
|
+
|
12
|
+
define_method timestamp_name do
|
13
|
+
unless instance_variable_get("@#{timestamp_name}".to_sym).respond_to? :strftime
|
14
|
+
instance_variable_set(
|
15
|
+
"@#{timestamp_name}".to_sym,
|
16
|
+
instance_variable_get("@#{timestamp_name}".to_sym).to_s.to_datetime
|
17
|
+
)
|
18
|
+
end
|
19
|
+
instance_variable_get("@#{timestamp_name}".to_sym)
|
17
20
|
end
|
18
21
|
end
|
19
|
-
|
20
22
|
end
|
23
|
+
|
21
24
|
end
|
22
|
-
end
|
25
|
+
end
|
@@ -1,73 +1,49 @@
|
|
1
1
|
require 'active_support/hash_with_indifferent_access'
|
2
2
|
|
3
|
-
module NaranyaEcm
|
4
|
-
|
5
|
-
class Key < String
|
3
|
+
module NaranyaEcm::Cache
|
4
|
+
class Key < String
|
6
5
|
|
7
|
-
|
6
|
+
TIMESTAMP_FORMAT = '%Y%m%d%H%M%S'.freeze
|
8
7
|
|
9
|
-
|
8
|
+
attr_reader :klass, :id, :timestamp
|
10
9
|
|
11
|
-
|
10
|
+
def initialize(given_class, given_id, given_timestamp = nil)
|
11
|
+
@klass, @id = given_class, given_id
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
@segments[:id] = case
|
23
|
-
when resource.present? then resource.id
|
24
|
-
when segments.has_key?(:id) then segments.delete(:id)
|
25
|
-
else nil
|
26
|
-
end
|
27
|
-
|
28
|
-
@segments[:timestamp] = case
|
29
|
-
when resource.present? then resource.respond_to?(:updated_at) ? resource.updated_at : nil
|
30
|
-
when segments.has_key?(:timestamp) then segments.delete(:timestamp)
|
31
|
-
else nil
|
13
|
+
unless given_timestamp.blank?
|
14
|
+
@timestamp = if given_timestamp.is_a? String
|
15
|
+
given_timestamp.to_datetime
|
16
|
+
elsif given_timestamp.respond_to? :strftime
|
17
|
+
given_timestamp
|
18
|
+
else
|
19
|
+
raise ArgumentError, "Given timestamp is not a Date|Time like object"
|
32
20
|
end
|
33
|
-
|
34
|
-
@segments.freeze
|
35
|
-
|
36
|
-
super self.class.join_segments(@segments).freeze
|
37
|
-
|
38
21
|
end
|
39
22
|
|
40
|
-
|
41
|
-
|
42
|
-
def timestamp; @segments[:timestamp]; end
|
23
|
+
super join_segments
|
24
|
+
end
|
43
25
|
|
44
|
-
|
45
|
-
|
46
|
-
|
26
|
+
def timestamped?
|
27
|
+
timestamp.present?
|
28
|
+
end
|
47
29
|
|
48
|
-
|
49
|
-
|
50
|
-
|
30
|
+
def exist?
|
31
|
+
NaranyaEcm.cache.exist? self
|
32
|
+
end
|
51
33
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
34
|
+
def read
|
35
|
+
NaranyaEcm.cache.read self
|
36
|
+
end
|
56
37
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
66
|
-
end
|
67
|
-
str
|
68
|
-
end
|
38
|
+
def write(data)
|
39
|
+
NaranyaEcm.cache.write self, data
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def join_segments
|
44
|
+
key = "#{klass.name.tableize}/#{id}"
|
45
|
+
timestamped? ? "#{key}-#{timestamp.strftime(TIMESTAMP_FORMAT)}" : key
|
69
46
|
end
|
70
47
|
|
71
|
-
end
|
72
48
|
end
|
73
49
|
end
|
@@ -1,82 +1,69 @@
|
|
1
1
|
require 'active_support/concern'
|
2
|
-
module NaranyaEcm
|
3
|
-
module Cache
|
4
|
-
module Methods
|
5
2
|
|
6
|
-
|
3
|
+
module NaranyaEcm::Cache
|
4
|
+
module Methods
|
7
5
|
|
8
|
-
|
9
|
-
alias_method_chain :load, :caching
|
6
|
+
extend ActiveSupport::Concern
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def cache_key
|
17
|
-
@cache_key ||= NaranyaEcm.cache_key_for resource: self
|
18
|
-
end
|
19
|
-
|
20
|
-
def load_with_caching(attributes, remove_root = false, persisted = false)
|
21
|
-
if self.new?
|
22
|
-
load_without_caching(attributes, remove_root, persisted)
|
23
|
-
else
|
24
|
-
res = load_without_caching(attributes, remove_root = false, persisted = false)
|
25
|
-
|
26
|
-
cache_options = {}
|
27
|
-
cache_options[:expires_in] = 10.minutes unless self.updated_at.present? and self.updated_at.is_a? DateTime
|
28
|
-
|
29
|
-
NaranyaEcm.cache.write cache_key, @attributes, cache_options
|
30
|
-
|
31
|
-
res
|
32
|
-
end
|
8
|
+
included do
|
9
|
+
class << self
|
10
|
+
alias_method_chain :find, :caching
|
11
|
+
alias_method_chain :find_one, :caching
|
33
12
|
end
|
13
|
+
end
|
34
14
|
|
35
|
-
|
15
|
+
def cache_key
|
16
|
+
self.new_resource? ? nil : self.class.cache_key_for(self.id, self.updated_at)
|
17
|
+
end
|
36
18
|
|
37
|
-
|
38
|
-
NaranyaEcm.cache
|
39
|
-
end
|
19
|
+
module ClassMethods
|
40
20
|
|
41
|
-
|
42
|
-
|
43
|
-
|
21
|
+
def cache
|
22
|
+
NaranyaEcm.cache
|
23
|
+
end
|
44
24
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
25
|
+
def cache_key_for(id, timestamp=nil)
|
26
|
+
Key.new self, id, timestamp
|
27
|
+
end
|
49
28
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
found
|
54
|
-
end
|
29
|
+
def find_with_caching(id, cache_options = {})
|
30
|
+
find_one_with_caching(id, cache_options)
|
31
|
+
end
|
55
32
|
|
56
|
-
|
33
|
+
private
|
57
34
|
|
58
|
-
|
59
|
-
|
60
|
-
|
35
|
+
# Find a single resource from the default URL
|
36
|
+
def find_one_with_caching(id, cache_options = {})
|
37
|
+
fetched_data = nil
|
38
|
+
missed = true
|
39
|
+
|
40
|
+
# Ver primero si lo podemos obtener del cache:
|
41
|
+
cache_timestamp = cache_options.delete(:timestamp)
|
42
|
+
if cache_timestamp.present?
|
61
43
|
# Try to load the record from cache:
|
62
|
-
cache_key = cache_key_for
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
unless record.present?
|
44
|
+
cache_key = cache_key_for(id, cache_timestamp)
|
45
|
+
missed = (fetched_data = cache_key.read).nil?
|
46
|
+
puts "===== CACHE #{(missed ? 'MISS: ' : 'HIT: ')} '#{cache_key}'"
|
47
|
+
end
|
67
48
|
|
68
|
-
|
69
|
-
record = find_single_without_caching(scope, options)
|
49
|
+
# Si no lo obtuvimos del caché, traer uno del server:
|
70
50
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
51
|
+
unless fetched_data.present?
|
52
|
+
fetched_data = fetch_one(id)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Inicializar el recurso con los datos obtenidos:
|
56
|
+
resource = self.load fetched_data
|
57
|
+
|
58
|
+
# Write unless data exists:
|
59
|
+
if missed
|
60
|
+
puts "===== Cache WRITE: '#{resource.cache_key}'"
|
61
|
+
cache.write(resource.cache_key, fetched_data)
|
77
62
|
end
|
78
|
-
end
|
79
63
|
|
64
|
+
resource
|
65
|
+
end
|
80
66
|
end
|
67
|
+
|
81
68
|
end
|
82
|
-
end
|
69
|
+
end
|
@@ -2,35 +2,58 @@ require 'active_support/concern'
|
|
2
2
|
require 'state_machine'
|
3
3
|
|
4
4
|
module NaranyaEcm
|
5
|
-
module Lifecycles
|
6
5
|
|
7
|
-
|
8
|
-
|
6
|
+
module ContentLifecycle
|
7
|
+
extend ActiveSupport::Concern
|
9
8
|
|
10
|
-
|
9
|
+
included do
|
11
10
|
|
12
|
-
|
11
|
+
state_machine :lifecycle_state, initial: :draft do
|
12
|
+
state :draft
|
13
|
+
state :awaiting_validation
|
14
|
+
state :accepted
|
15
|
+
state :rejected
|
16
|
+
state :published
|
17
|
+
state :inactive
|
13
18
|
|
14
|
-
|
15
|
-
|
16
|
-
|
19
|
+
event :send_to_validation do
|
20
|
+
transition :draft => :awaiting_validation
|
21
|
+
end
|
17
22
|
|
18
|
-
|
23
|
+
event :accept do
|
24
|
+
transition :awaiting_validation => :accepted
|
25
|
+
end
|
19
26
|
|
20
|
-
|
27
|
+
event :reject do
|
28
|
+
transition [:awaiting_validation, :published] => :rejected
|
29
|
+
end
|
21
30
|
|
22
|
-
|
31
|
+
event :publish do
|
32
|
+
transition :draft => :published, if: :simple_lifecycle?
|
33
|
+
transition :accepted => :published, if: :validation_lifecycle?
|
34
|
+
end
|
23
35
|
|
24
|
-
|
36
|
+
event :deactivate do
|
37
|
+
transition any => :inactive
|
38
|
+
end
|
25
39
|
|
26
|
-
|
40
|
+
######
|
41
|
+
after_transition :on => any, do: :commit_lifecycle_state_change!
|
42
|
+
end
|
27
43
|
|
28
|
-
|
44
|
+
|
45
|
+
end
|
29
46
|
|
30
|
-
|
31
|
-
|
47
|
+
def simple_lifecycle?; self.lifecycle_name == 'simple'; end
|
48
|
+
def validation_lifecycle?; self.lifecycle_name == 'validation'; end
|
32
49
|
|
50
|
+
def commit_lifecycle_state_change!(transition)
|
51
|
+
off_band_changes["#{transition.attribute}_event"] = transition.event
|
52
|
+
self.send "reset_#{transition.attribute}!".to_sym
|
53
|
+
self.save
|
33
54
|
end
|
34
55
|
|
56
|
+
|
35
57
|
end
|
58
|
+
|
36
59
|
end
|
@@ -1,40 +1,21 @@
|
|
1
|
-
require 'active_resource'
|
2
1
|
|
3
|
-
module NaranyaEcm
|
4
|
-
class Category
|
5
|
-
|
6
|
-
include NaranyaEcm::Behaviors::Resourceable
|
2
|
+
module NaranyaEcm
|
3
|
+
class Category
|
7
4
|
|
5
|
+
include NaranyaEcm.document_module
|
8
6
|
include NaranyaEcm::Behaviors::Timestampable
|
9
|
-
|
10
|
-
include NaranyaEcm::Search::Methods
|
11
7
|
include NaranyaEcm::Cache::Methods
|
8
|
+
include NaranyaEcm::Search::Methods
|
9
|
+
include NaranyaEcm::Behaviors::Mediable
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
self.include_root_in_json = true
|
18
|
-
|
19
|
-
# Definir los atributos conocidos:
|
20
|
-
schema do
|
21
|
-
# define each attribute separately
|
22
|
-
string :id, :code, :created_at, :updated_at
|
23
|
-
|
24
|
-
# unsupported types should be left as strings
|
25
|
-
# overload the accessor methods if you need to convert them
|
26
|
-
#attribute 'created_at', 'string'
|
27
|
-
attribute 'name_translations', 'string'
|
28
|
-
attribute 'description_translations', 'string'
|
29
|
-
|
30
|
-
end
|
11
|
+
field :code, type: String
|
12
|
+
validates :code, presence: true
|
31
13
|
|
32
|
-
|
33
|
-
|
14
|
+
field :name, type: String, localize: true
|
15
|
+
|
16
|
+
has_many :media_resources
|
34
17
|
|
35
|
-
|
36
|
-
Content.find :all, params: { category_id: self.id }
|
37
|
-
end
|
18
|
+
has_many :contents
|
38
19
|
|
39
20
|
end
|
40
21
|
end
|
@@ -1,84 +1,84 @@
|
|
1
|
-
require 'active_resource'
|
2
1
|
|
3
|
-
module NaranyaEcm
|
4
|
-
class Content
|
2
|
+
module NaranyaEcm
|
3
|
+
class Content
|
5
4
|
|
6
|
-
include
|
7
|
-
|
8
|
-
include NaranyaEcm::Behaviors::Resourceable
|
9
|
-
|
10
|
-
include NaranyaEcm::Search::Methods
|
5
|
+
include NaranyaEcm.document_module
|
6
|
+
include NaranyaEcm::Behaviors::Timestampable
|
11
7
|
include NaranyaEcm::Cache::Methods
|
8
|
+
include NaranyaEcm::Search::Methods
|
9
|
+
include NaranyaEcm::Behaviors::Mediable
|
10
|
+
|
11
|
+
# Type:
|
12
|
+
# Describes the main type of the content - App, Note, etc.
|
13
|
+
field :type, type: String
|
14
|
+
|
15
|
+
# Content Lifecycle Name:
|
16
|
+
# Determines the lifecycle for the specific content:
|
17
|
+
# - simple: draft -> published -> inactive
|
18
|
+
# - validatable: draft -> awaiting_validation -> validated -> published -> inactive
|
19
|
+
# - expirable: draft -> published -> expired/inactive
|
20
|
+
field :lifecycle_name, type: String, default: -> { 'simple' }
|
21
|
+
validates :lifecycle_name, presence: true
|
22
|
+
|
23
|
+
# Content Lifecycle State:
|
24
|
+
# A managed string that describes the current state of this particular content.
|
25
|
+
# Depending on the Content's lifecycle, it changes upon several events.
|
26
|
+
# - draft:
|
27
|
+
# - awaiting_validation:
|
28
|
+
# - validated:
|
29
|
+
# - invalidated:
|
30
|
+
# - published:
|
31
|
+
field :lifecycle_state, type: String, default: -> { :draft }
|
32
|
+
validates :lifecycle_state, presence: true
|
33
|
+
|
34
|
+
# Title (Localized):
|
35
|
+
# The content title that can be displayed as header, result, etc.
|
36
|
+
field :title, type: String, localize: true
|
37
|
+
validate :at_least_one_title_translation_must_exist
|
38
|
+
|
39
|
+
# Description (Localized):
|
40
|
+
# The content title that can be displayed as header, result, etc.
|
41
|
+
field :description, type: String, localize: true
|
12
42
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
attribute 'title_translations', 'string'
|
38
|
-
attribute 'description_translations', 'string'
|
39
|
-
attribute 'keywords', 'string'
|
40
|
-
|
41
|
-
if NaranyaEcm.options[:extra_attributes] && NaranyaEcm.options[:extra_attributes][:content]
|
42
|
-
NaranyaEcm.options[:extra_attributes][:content].each { |key, val| attribute key, val }
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
schema_attrs = self.schema.keys.map(&:to_sym)
|
48
|
-
define_attribute_methods(*schema_attrs)
|
49
|
-
schema_attrs.each do |attr_sym|
|
50
|
-
# getter:
|
51
|
-
define_method(attr_sym) { @attributes[attr_sym] }
|
52
|
-
# setter:
|
53
|
-
define_method("#{attr_sym}=".to_sym) do |value|
|
54
|
-
self.send "#{attr_sym}_will_change!".to_sym unless value == @attributes[attr_sym]
|
55
|
-
@attributes[attr_sym] = value
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
delegate :title, to: :title_translations
|
60
|
-
delegate :description, to: :description_translations
|
61
|
-
|
62
|
-
def initialize(attributes = {}, persisted = false)
|
63
|
-
super
|
64
|
-
attributes[:title_translations] = TitleTranslations.new unless attributes[:title_translations].present?
|
65
|
-
attributes[:description_translations] = DescriptionTranslations.new unless attributes[:description_translations].present?
|
66
|
-
attributes[:content_rating] = ContentRating.new unless attributes[:content_rating].present?
|
67
|
-
end
|
43
|
+
# Content Rating:
|
44
|
+
field :content_rating, type: Hash
|
45
|
+
|
46
|
+
# Keywords:
|
47
|
+
field :keywords, type: Array
|
48
|
+
|
49
|
+
# Author:
|
50
|
+
# The name of the user who created this content.
|
51
|
+
field :author, type: String
|
52
|
+
validates :author,
|
53
|
+
presence: true
|
54
|
+
|
55
|
+
# Main URL:
|
56
|
+
# The URL that should be used to render or display the content.
|
57
|
+
field :main_url, type: String
|
58
|
+
validates :main_url,
|
59
|
+
format: { with: URI.regexp },
|
60
|
+
allow_nil: true,
|
61
|
+
allow_blank: true
|
62
|
+
|
63
|
+
belongs_to :category
|
64
|
+
|
65
|
+
has_many :versions,
|
66
|
+
class_name: :ContentVersion
|
68
67
|
|
69
|
-
|
68
|
+
belongs_to :current_version,
|
69
|
+
class_name: :ContentVersion
|
70
70
|
|
71
|
-
|
71
|
+
has_many :media_resources,
|
72
|
+
class_name: :MediaResource,
|
73
|
+
inverse_of: :content
|
72
74
|
|
73
|
-
|
74
|
-
unless self.attributes[:keywords].is_a?(Array)
|
75
|
-
self.attributes[:keywords] = if self.attributes[:keywords]=='' then []
|
76
|
-
else [self.attributes[:keywords]]
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
75
|
+
include NaranyaEcm::ContentLifecycle
|
80
76
|
|
81
|
-
|
77
|
+
private
|
78
|
+
|
79
|
+
def at_least_one_title_translation_must_exist
|
80
|
+
errors.add :title_translations, "must have at least one translation" unless title_translations.keys.any?
|
81
|
+
end
|
82
82
|
|
83
83
|
end
|
84
84
|
end
|