naranya_ecm-sdk 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- 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
|