pages/app/models/constructor_pages/field.rb
module ConstructorPages
# Field model. Fields allows to add custom fields for template.
# Each field has type of value such as float, integer, string...
class Field < ActiveRecord::Base
# Array of available field types
TYPES = %w{string integer float boolean text date html image}
TYPES.each {|t| class_eval %{has_many :#{t}_types, class_name: 'Types::#{t.titleize}Type'} }
validates_presence_of :name
validates_uniqueness_of :code_name, scope: :template_id
validate :code_name_uniqueness
after_create :create_page_fields
after_destroy :destroy_all_page_fields
has_many :pages, through: :template
belongs_to :template
acts_as_list scope: :template_id
default_scope -> { order :position }
# Return constant of model type_value
def type_class; "constructor_pages/types/#{type_value}_type".classify.constantize end
# Return object of type_value by page
def find_type_object(page); type_class.find_by(field_id: id, page_id: page.id) end
# Create object of type_value by page
def create_type_object(page); type_class.create(field_id: id, page_id: page.id) end
# Find or create type object by page
def find_or_create_type_object(page); find_type_object(page) || create_type_object(page) end
# Remove all type_fields values for specified page
def remove_type_object(page); find_type_object(page).destroy end
# Get value from type_field for specified page
def get_value_for(page); find_type_object(page).tap {|t| return t && t.value} end
# Set value type_field for specified page
def set_value_for(page, value); find_type_object(page).tap {|t| t || return; t.update value: value} end
private
# Check if code_name is not available
def code_name_uniqueness
errors.add(:base, :code_name_already_in_use) unless Page.check_code_name(code_name) and check_code_name(code_name)
end
# Check if there is code_name in template branch
def check_code_name(code_name)
[code_name.pluralize, code_name.singularize].each {|name|
%w{self_and_ancestors descendants}.each {|m|
return false if template.send(m).map(&:code_name).include?(name)}}
true
end
def create_page_fields
template.page_ids.each_slice(500) do |batch|
_items = []
batch.each do |_id|
_items << type_class.new({page_id: _id, field_id: id})
end
type_class.import _items
end
end
def destroy_all_page_fields
template.page_ids.each_slice(1000) do |batch|
type_class.where(page_id: batch, field_id: id).delete_all
Page.update_all({updated_at: Time.now}, {id: batch})
end
end
end
end