Module: Alchemy::Essence::ClassMethods

Defined in:
lib/alchemy/essence.rb

Overview

Delivers various methods we need for Essences in Alchemy.

To turn a model into an essence call acts_as_essence inside your model and you will get:

* validations
* several getters (ie: page, element, content, ingredient, preview_text)

Instance Method Summary collapse

Instance Method Details

#_reflect_on_association(name) ⇒ Object

Overwrite ActiveRecords method to return a bogus association class that skips eager loading for essence classes that do not have an ingredient association


98
99
100
101
102
103
104
# File 'lib/alchemy/essence.rb', line 98

def _reflect_on_association(name)
  if name == :ingredient_association && !in?(@_classes_with_ingredient_association)
    OpenStruct.new(association_class: Alchemy::IngredientAssociation)
  else
    super
  end
end

#acts_as_essence(options = {}) ⇒ Object

Turn any active record model into an essence by calling this class method

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • ingredient_column (String || Symbol) — default: 'body'

    specifies the column name you use for storing the content in the database (default: body)

  • validate_column (String || Symbol) — default: ingredient_column

    The column the the validations run against.

  • preview_text_column (String || Symbol) — default: ingredient_column

    Specify the column for the preview_text method.


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/alchemy/essence.rb', line 39

def acts_as_essence(options = {})
  register_as_essence_association!

  configuration = {
    ingredient_column: "body",
  }.update(options)

  @_classes_with_ingredient_association ||= []

  class_eval <<-RUBY, __FILE__, __LINE__ + 1
    attr_writer :validation_errors
    include Alchemy::Essence::InstanceMethods

    validate :validate_ingredient, on: :update, if: -> { validations.any? }

    has_one :content, as: :essence, class_name: "Alchemy::Content", inverse_of: :essence
    has_one :element, through: :content, class_name: "Alchemy::Element"
    has_one :page,    through: :element, class_name: "Alchemy::Page"

    scope :available,    -> { joins(:element).merge(Alchemy::Element.available) }
    scope :from_element, ->(name) { joins(:element).where(Element.table_name => { name: name }) }

    delegate :restricted?, to: :page,    allow_nil: true
    delegate :trashed?,    to: :element, allow_nil: true
    delegate :public?,     to: :element, allow_nil: true

    after_save :touch_element

    def acts_as_essence_class
      #{name}
    end

    def ingredient_column
      '#{configuration[:ingredient_column]}'
    end

    def validation_column
      '#{configuration[:validate_column] || configuration[:ingredient_column]}'
    end

    def preview_text_column
      '#{configuration[:preview_text_column] || configuration[:ingredient_column]}'
    end
  RUBY

  if configuration[:belongs_to]
    class_eval <<-RUBY, __FILE__, __LINE__ + 1
      belongs_to :ingredient_association, #{configuration[:belongs_to]}

      alias_method :#{configuration[:ingredient_column]}, :ingredient_association
      alias_method :#{configuration[:ingredient_column]}=, :ingredient_association=
    RUBY

    @_classes_with_ingredient_association << self
  end
end