class FoxPage::Model
Constants
- DEFAULT_STORAGE_TYPE
- VALID_STORAGE_TYPES
Public Class Methods
[](storage_type = DEFAULT_STORAGE_TYPE, storage_type_opts = {})
click to toggle source
# File lib/fox_page/model.rb, line 20 def self.[](storage_type = DEFAULT_STORAGE_TYPE, storage_type_opts = {}) unless VALID_STORAGE_TYPES.include?(storage_type) raise ArgumentError, "type must be one of #{VALID_STORAGE_TYPES.join(',')}" end @__tmp_storage_type = storage_type @__tmp_storage_type_opts = storage_type_opts self end
all()
click to toggle source
# File lib/fox_page/model.rb, line 133 def self.all @__data end
belongs_to(what, referenced_by: :name)
click to toggle source
e.g. in Project: belongs_to
:project_category, referenced_by: :name
# File lib/fox_page/model.rb, line 96 def self.belongs_to(what, referenced_by: :name) association_class = Kernel.const_get(what.to_s.camelize) define_method("__#{what}_value") do @__ostruct[what] end define_method(what) do association_class.find(referenced_by => public_send("__#{what}_value")) end end
def_parser(attribute, &parser)
click to toggle source
define a parser method for attributes @example
require "time" class BlogPost < FoxPage::Model[:dir] def_parser :date do |date| Time.parse(date) end end # in the blog posts' front matter: # --- # title: foo # date: Sat 13 Jul 13:38:43 CEST 2019 # --- # then, anywhere else: blog_post.date # => 2019-07-13 13:38:43 +0200 blog_post.date.class # => Time
# File lib/fox_page/model.rb, line 127 def self.def_parser(attribute, &parser) define_method(attribute) do parser.call(@__ostruct[attribute]) end end
each(&block)
click to toggle source
# File lib/fox_page/model.rb, line 137 def self.each(&block) @__data.each(&block) end
find(filter)
click to toggle source
# File lib/fox_page/model.rb, line 141 def self.find(filter) @__data.find do |object| filter.all? do |key, value| value_key_name = "__#{key}_value" key = value_key_name if object.respond_to?(value_key_name) object.public_send(key) == value end end end
has_many(what, referenced_by: nil)
click to toggle source
e.g. in ProjectCategory: has_many
:projects, referenced_by: nil
nil = default of self.class.name underscored
# File lib/fox_page/model.rb, line 86 def self.has_many(what, referenced_by: nil) # rubocop:disable Naming/PredicateName, Metrics/LineLength referenced_by ||= name.to_s.underscore association_class = Kernel.const_get(what.to_s.singularize.camelize) define_method(what.to_s) do association_class.where(referenced_by => name.to_s) end end
inherited(subclass)
click to toggle source
# File lib/fox_page/model.rb, line 32 def self.inherited(subclass) set_ivar_if_unset subclass, :storage_type, DEFAULT_STORAGE_TYPE set_ivar_if_unset subclass, :storage_type_opts, {} subclass.reload_all(@__app) end
new(ostruct)
click to toggle source
# File lib/fox_page/model.rb, line 169 def initialize(ostruct) @__ostruct = ostruct end
reload_all(app)
click to toggle source
# File lib/fox_page/model.rb, line 51 def self.reload_all(app) data_name = name.to_s.underscore.pluralize puts "MODEL\t#{data_name}" case @__storage_type when :yaml @__data = YAML.load_file( app.root.join("data", data_name + ".yml") ).to_deep_ostruct.map { |ostruct| new(ostruct) } when :dir default_opts = { extension: :md } opts = default_opts.merge(@__storage_type_opts) base_data_dir = app.root.join("data", data_name) files = Dir[File.join(base_data_dir, "**", "*.#{opts.fetch(:extension)}")] @__data = files.map do |fn| id = File.join(File.dirname(fn).sub(/\A#{base_data_dir}/, ""), File.basename(fn, ".#{opts.fetch(:extension)}")) .sub(/\A(?:#{File::SEPARATOR})/, "") content = IO.read(fn) front_matter = {} if content =~ /\A(---\n.*\n)^(?:---)\s*$\n?/m content = Regexp.last_match.post_match front_matter = YAML.safe_load(Regexp.last_match[1], [Time]) end new front_matter.merge(id: id, content: content).to_deep_ostruct end end end
where(filter)
click to toggle source
# File lib/fox_page/model.rb, line 152 def self.where(filter) @__data.select do |object| filter.all? do |key, value| value_key_name = "__#{key}_value" key = value_key_name if object.respond_to?(value_key_name) returned_value = object.public_send(key) case returned_value when Array returned_value.include?(value) else returned_value == value end end end end
Private Class Methods
set_ivar_if_unset(subclass, ivar, default)
click to toggle source
# File lib/fox_page/model.rb, line 39 def self.set_ivar_if_unset(subclass, ivar, default) target_ivar = :"@__#{ivar}" return if subclass.instance_variable_get(target_ivar) tmp_ivar = :"@__tmp_#{ivar}" value = instance_variable_get tmp_ivar instance_variable_set tmp_ivar, nil subclass.instance_variable_set target_ivar, value || default end
Public Instance Methods
method_missing(method, *args, &block)
click to toggle source
Calls superclass method
# File lib/fox_page/model.rb, line 173 def method_missing(method, *args, &block) hash_ostruct = @__ostruct.to_h return super unless hash_ostruct.key?(method.to_sym) hash_ostruct[method.to_sym] end
respond_to_missing?(method, *)
click to toggle source
Calls superclass method
# File lib/fox_page/model.rb, line 180 def respond_to_missing?(method, *) return true if @__ostruct.to_h.key?(method.to_sym) super end