Как узнать текущий класс внутри общей проблемы - PullRequest
0 голосов
/ 31 октября 2018

У меня есть 3 модели, каждая из которых имеет столбец hstore, который потенциально содержит те же 4 атрибута. Код для облегчения этих атрибутов hstore включает вызов store_accessor, метод, используемый для совместного использования этих атрибутов hstore со строгими параметрами, и пару других методов.

Очень похожий, если не точный, код существует в 3 разных классах.

Вызов store_accessor фактически заключен в цикл, который проходит через метод класса, который возвращает список имен атрибутов (которые могут быть или не быть уникальными для каждой из 3 моделей).

class Foo

  def self.array_of_attrs
    %w(one two three)
  end

  Foo.array_of_attrs.each do |a|
    ...
    store_accessor :hstore_col_name, "#{ a }_yada_yada".to_sym
  end

достаточно просто ... Однако я бы хотел перенести весь этот код в раздел проблем (шик, шипение) и поделиться этим подходом с каждым из 3 затронутых классов. Проблема, с которой я столкнулся, состоит в том, что ... я не знаю, какой класс в настоящее время вызывает проблему. Другими словами, Foo, это не Foo ... это какой-либо из 3 классов, использующих беспокойство.

Внутри концерна, как я могу использовать текущий класс? В этом примере, как бы я динамически вызывал текущий класс вместо вызова класса Foo?

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Когда вы используете included в концерне, включающий класс передается в качестве аргумента блоку:

module Bar
  extend ActiveSupport::Concern
  included do |base|
    base.array_of_attrs.each do |a|
     # ...
     store_accessor :hstore_col_name, "#{ a }_yada_yada".to_sym
    end
  end
end

class Foo < ApplicationRecord
  include Bar
end

И да, вы должны использовать included, поскольку методы доступа объявляются в контексте класса.

Помните, что это просто синтаксический сахар для:

module Baz
  def self.included(base)
    base.class_eval do
      # ...
    end
  end
end
0 голосов
/ 01 ноября 2018

Проверьте это:

module Foo
  def self.included(base)
    base.class_eval do

      def self.some_method
        array_of_attrs.each do |a|
          ...
          store_accessor :hstore_col_name, "#{ a }_yada_yada".to_sym
        end
      end

    end
  end
end

class Model < ApplicationRecord
  include Foo

  def self.array_of_attrs
    %w(one two three)
  end
end

Model.some_method
...