简体   繁体   中英

Access Rails class const from within extended relation module

I'm having an inheritance/mixin brain fart and was wondering if someone felt like enlightening me.

I use query classes throughout my app to encapsulate complex, role-specific queries. For instance there may be a PostQuery class and a PhotoQuery class.

I also have a base query class that exposes generic relation extensions for things such as pagination.

The problem I'm having is that I want to access constants that are defined in the including class from the base relation methods, but no matter what combination of inheritance/inclusion I've tried, its eluding me.

I've posted a simple gist below with a simplified broken example. Cheers.

https://gist.github.com/uberllama/9e69529b0d835902f33d

Convoluted workaround based on a question i had earlier - use self.inherited(sub_klass) in the base class to call sub_klass.const_get . Then use this to send define_method to sub_klass with the subclass's constants.

Ruby Metaprogramming: Dynamically defining method based on child instance attribute

class BaseQuery

  ALLOWED_SORT_ATTRS = []

  def initialize(relation)
    @relation = relation.extending(Scopes)
  end

  def self.inherited(sub_klass)
    sub_klass.send(:define_method, 'allowed_sort_attrs') do
      sub_klass.const_get(:ALLOWED_SORT_ATTRS)
    end
    sub_klass.send(:define_method, 'scoped') do
      Scope.new(sub_klass)
    end
  end

  class Scope
    def initialize(klass)
      @klass = klass 
    end

    def sorted(sort_param, sort_direction)
      if klass.allowed_sort_attrs.include(sort_param)
        order("#{sort_param} #{sort_direction}")
      else
        order("id DESC")
      end
    end
  end

end

For now, I've decided to just interpolate the current relation within the methods to get at the const.

def sorted
  allowed_attr_names = "#{klass}Query".constantize.const_get(:ALLOWED_ATTR_NAMES)
end

In this case, if I'm within a Post relation, it'll retrieve PostQuery::ALLOWED_ATTR_NAMES

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM