Уменьшите количество методов экземпляра - PullRequest
0 голосов
/ 13 октября 2018

Я моделирую отчет как класс, а значение каждого столбца - как метод доступа.Каждое значение в отчете должно быть доступно из базы данных.Но из-за этого класс выглядит довольно толстым, и RubyMine предупреждает меня о слишком большом количестве методов в классе.

class Report

attr_accessor :name, :col1, :col2, :col3 .... :col15

def col1
 db.find({x: 1})['some_var']
end

def col2
 db.find({y: 4})['some_other_var']
end

and so forth for each attribute...

end

Поскольку каждый метод get является по существу одной строкой, которая выполняет вызов к базе данных, существует более простой способ объявить эти переменныебез использования метода?

Я не хочу устанавливать их в методе initialize, поскольку эти отчеты будут разделены на подклассы, а дочерние отчеты не будут иметь все / некоторые из этих атрибутов.

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Вы можете использовать метапрограммирование для создания методов типа attr_accessor на лету.

Например:

class Report
  def initialize(attributes)
    attributes.each do |attribute|
      define_singleton_method :"#{attribute}" do |hash_param, string_param|
        db.find(hash_param)[string_param]
      end
    end
  end
end

Затем вы можете создать новый объект отчета и передать имена атрибутов следующим образом:

r = Report.new(["n","m"])

Теперь вы можете вызывать n и m методы для r объекта

r.m({val1: "val1"}, "val2")
r.n({val2: "val1"}, "val2")
0 голосов
/ 13 октября 2018

@ Рахул, основываясь на ответе на мой вопрос, единственный совет, который я могу дать здесь, - это использовать лучшие принципы проектирования ООП.Подкласс и модульный, где это возможно, а также с использованием ruby ​​метапрограммирования.Если вам нужны методы, они должны быть где-то написаны.Но если вам нужны только геттеры, рассмотрите attr_reader, если вам не нужны и сеттеры.

Если вы можете получить имена столбцов, вы можете использовать динамическое определение метода с чем-то вроде этого, предполагая, что db волшебным образом определено там, где вы еще не ясно, мы будем предполагать, что это соединение с базой данных.

class Report

  db.column_names.each do |col|
    define_method(col.to_sym) { db.find(options={}) }
  end

end

Если вы просто хотите, чтобы RubyMine прекратил вас раздражать, я полагаю, что он использует rubocop, и вы можете увидеть этот пост о том, как переопределить правила.

https://www.jetbrains.com/help/ruby/2017.1/rubocop.html

или

https://github.com/rubocop-hq/rubocop

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...