Class: ContentsCore::Block

Inherits:
ApplicationRecord show all
Defined in:
app/models/contents_core/block.rb

Constant Summary collapse

EMPTY_DATA =
OpenStruct.new( { data: '' } )

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}, &block) ⇒ Block

after_validation :on_after_validation

field :block_type, type: String, default: ‘text’ field :name, type: String, default: ” field :position, type: Integer, default: 0 field :published, type: Mongoid::Boolean, default: true field :_init, type: Mongoid::Boolean, default: false

embedded_in :parent, polymorphic: true

embeds_many :cc_blocks, cascade_callbacks: true, order: :position.desc, class_name: ‘ContentsCore::Block’ embeds_many :items, cascade_callbacks: true, class_name: ‘ContentsCore::Item’

accepts_nested_attributes_for :cc_blocks, allow_destroy: true accepts_nested_attributes_for :items

# scope :published, -> { where( published: true ) unless ApplicationController.edit_mode }



56
57
58
59
60
61
# File 'app/models/contents_core/block.rb', line 56

def initialize( attributes = {}, &block )
  super( attributes, &block )
  @create_children = 1
  self.group = config[:group]
  self.block_type = parent.config[:children_type] if attributes[:block_type].nil? && self.parent_type == 'ContentsCore::Block'
end

Instance Attribute Details

#create_childrenObject

Returns the value of attribute create_children.



5
6
7
# File 'app/models/contents_core/block.rb', line 5

def create_children
  @create_children
end

Class Method Details

.block_enum(include_children = true) ⇒ Object



185
186
187
# File 'app/models/contents_core/block.rb', line 185

def self.block_enum( include_children = true )
  ContentsCore.config[:cc_blocks].map{|k, v| [v[:name], k.to_s] if !include_children || !v[:child_only]}.compact.sort_by{|b| b[0]}
end

.block_types(include_children = true) ⇒ Object



189
190
191
# File 'app/models/contents_core/block.rb', line 189

def self.block_types( include_children = true )
  ContentsCore.config[:cc_blocks].select{|k, v| !include_children || !v[:child_only]}.keys
end

.init_items(block, items, options = {}) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'app/models/contents_core/block.rb', line 193

def self.init_items( block, items, options = {} )
  items.each do |name, type|
    t = type.to_sym
    if type.to_s.start_with? 'item_'
      c = 'ContentsCore::' + ActiveSupport::Inflector.camelize( t )
      begin
        model = c.constantize
      rescue Exception => e
        Rails.logger.error '[ERROR] ContentsCore - init_items: ' + e.message
        model = false
      end
      block.items << model.new( name: name ).init if model
    elsif Block::block_types( false ).include? t.to_sym
      block.create_children.times do
        block.cc_blocks << Block.new( block_type: t, name: name )
      end
    end
  end if items
end

.permitted_attributesObject



213
214
215
# File 'app/models/contents_core/block.rb', line 213

def self.permitted_attributes
  [ :id, :name, :block_type, :position, :_destroy, items_attributes: [ :id ] + Item::permitted_attributes, cc_blocks_attributes: [ :id, :name, :block_type, items_attributes: [ :id ] + Item::permitted_attributes ] ]
end

Instance Method Details

#as_json(options = nil) ⇒ Object



63
64
65
# File 'app/models/contents_core/block.rb', line 63

def as_json( options = nil )
  super({ only: [:id, :block_type, :name, :group, :position, :published], include: [:cc_blocks, :items]}.merge(options || {}))
end

#attr_idObject



67
68
69
# File 'app/models/contents_core/block.rb', line 67

def attr_id
  "#{self.class.to_s.split('::').last}-#{self.id}"
end

#children_typeObject



71
72
73
# File 'app/models/contents_core/block.rb', line 71

def children_type
  config[:children_type]
end

#configObject



75
76
77
# File 'app/models/contents_core/block.rb', line 75

def config
  ContentsCore.config[:cc_blocks][block_type.to_sym] ? ContentsCore.config[:cc_blocks][block_type.to_sym] : {}
end

#create_item(item_type, item_name = nil) ⇒ Object



79
80
81
82
83
84
# File 'app/models/contents_core/block.rb', line 79

def create_item( item_type, item_name = nil )
  new_item = ContentsCore::Item.new( type: item_type )
  new_item.name = item_name if item_name
  self.items << new_item
  new_item
end

#editableObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'app/models/contents_core/block.rb', line 86

def editable
  ContentsCore.editing ? (
    is_sub_block? ?
    {
      'data-ec-sub-block': self.id,
      'data-ec-ct': self.block_type,
      'data-ec-position': self.position,
      'data-ec-pub': self.published
    } :
    {
      'data-ec-block': self.id,
      'data-ec-container': self.children_type,
      'data-ec-ct': self.block_type,
      'data-ec-pub': self.published
    }
  ).map { |k, v| "#{k}=\"#{v}\"" }.join( ' ' ).html_safe : ''
end

#get(name) ⇒ Object

Returns an item by name



105
106
107
108
# File 'app/models/contents_core/block.rb', line 105

def get( name )
  item = get_item( name )
  item.data if item
end

#get_item(name) ⇒ Object



110
111
112
113
114
115
116
# File 'app/models/contents_core/block.rb', line 110

def get_item( name )
  unless @_items
    @_items = {}
    items.each { |item| @_items[item.name] = item }
  end
  @_items[name]
end

#has_children?Boolean

Returns:

  • (Boolean)


122
123
124
# File 'app/models/contents_core/block.rb', line 122

def has_children?
  cc_blocks.exists?
end

#has_parent?Boolean

Returns:

  • (Boolean)


118
119
120
# File 'app/models/contents_core/block.rb', line 118

def has_parent?
  parent.present?
end

#is_sub_block?Boolean

Returns:

  • (Boolean)


126
127
128
# File 'app/models/contents_core/block.rb', line 126

def is_sub_block?
  parent.present? && parent_type == 'ContentsCore::Block'
end

#on_after_createObject



130
131
132
133
# File 'app/models/contents_core/block.rb', line 130

def on_after_create
  # TODO: validates type before creation!
  Block::init_items( self, config[:items] ) if Block::block_types( false ).include?( self.block_type.to_sym )
end

#on_before_createObject



135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/models/contents_core/block.rb', line 135

def on_before_create
  if self.name.blank?
    names = parent.cc_blocks.map( &:name )
    i = 0
    while( ( i += 1 ) < 1000 )  # Search an empty group
      unless names.include? "#{block_type}-#{i}"
        self.name = "#{block_type}-#{i}"
        break
      end
    end
  end
end

#propsObject



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'app/models/contents_core/block.rb', line 148

def props
  pieces = {}

  Item::item_types.each do |type|
    pieces[type.pluralize.to_sym] = []
  end
  items.each do |item|  # TODO: improve me
    pieces[item.class.type_name.pluralize.to_sym].push item
  end
  Item::item_types.each do |type|
    pieces[type.to_sym] = pieces[type.pluralize.to_sym].any? ? pieces[type.pluralize.to_sym].first : nil  # EMPTY_DATA - empty Item per sti class?
  end

  # pieces = {
  #   images:   items.select { |item| item.type == ItemImage.to_s },
  #   integers: items.select { |item| item.type == ItemInteger.to_s },
  #   strings:  items.select { |item| item.type == ItemString.to_s },
  #   texts:    items.select { |item| item.type == ItemText.to_s },
  # }

  # pieces[:image]  = pieces[:images].any?  ? pieces[:images].first  : EMPTY_DATA
  # pieces[:integers]  = pieces[:integers].any?  ? pieces[:integers].first  : EMPTY_DATA
  # pieces[:string] = pieces[:strings].any? ? pieces[:strings].first : EMPTY_DATA
  # pieces[:text]   = pieces[:texts].any?   ? pieces[:texts].first   : EMPTY_DATA

  OpenStruct.new( pieces )
end

#set(name, value) ⇒ Object



176
177
178
179
180
181
182
183
# File 'app/models/contents_core/block.rb', line 176

def set( name, value )
  items.each do |item|
    if item.name == name
      item.data = value
      break
    end
  end
end