module Resonate::ClassMethods

Public Instance Methods

resonate(subject, with: nil, by: nil, **options) click to toggle source
# File lib/resonate.rb, line 14
    def resonate(subject, with: nil, by: nil, **options)
      @roles = { source: subject, target: with, action: by }
      @options = options

      if @roles.values.any?(&:nil?)
        raise Resonate::Errors::ArgumentError, 'Passed argument is not a valid'
      end

      classify(source).class_eval <<-EOS
        has_many :#{pluralize(action)},
          foreign_key: :#{source}_id,
          dependent: :destroy

        has_many :#{progressize(action)},
          through: :#{pluralize(action)},
          source: :target_#{target}

        def #{action}(target)
          if #{progressize(action)}?(target) || (self == target)
            return
          end

          #{pluralize(action)}.create(#{foreign_key}: target.id)
        end

        def un#{action}(target)
          unless #{progressize(action)}?(target)
            return
          end

          #{pluralize(action)}.find_by(#{foreign_key}: target.id).destroy
        end

        def #{progressize(action)}?(target)
          #{pluralize(action)}.exists?(#{foreign_key}: target.id)
        end
      EOS

      classify(target).class_eval <<-EOS
        has_many :#{pluralize(action)}_as_target,
          foreign_key: :#{foreign_key},
          class_name: '#{classify(action)}',
          dependent: :destroy

        has_many :#{peoplize(action)},
          through: :#{pluralize(action)}_as_target,
          source: :#{source}

        def #{pastize(action)}_by?(source)
          source.#{pluralize(action)}.exists?(#{foreign_key}: id)
        end
      EOS

      classify(action).class_eval <<-EOS
        belongs_to :#{source}

        belongs_to :target_#{target},
          class_name: '#{classify(target)}',
          foreign_key: :#{foreign_key}
      EOS
    end

Private Instance Methods

action() click to toggle source
# File lib/resonate.rb, line 86
def action
  @roles[:action].to_s
end
foreign_key() click to toggle source
# File lib/resonate.rb, line 90
def foreign_key
  @options[:foreign_key] || "target_#{target}_id"
end
source() click to toggle source
# File lib/resonate.rb, line 78
def source
  @roles[:source].to_s
end
target() click to toggle source
# File lib/resonate.rb, line 82
def target
  @roles[:target].to_s
end