Перезаписать has_many getter - PullRequest
2 голосов
/ 28 октября 2019

У меня есть следующая модель:

class Metric < ApplicationRecord
  has_many key_phrases
end

И я хочу создать метод, который перезаписывает получатель key_phrases, что-то вроде:

class Metric < ApplicationRecord
  has_many key_phrases

  def key_phrases
    # if current value is not an empty array, return, otherwise creates, something like:
    current_value = super()
    return current_value unless current_value.nil?

    get_key_phrases.each do |k|
      key_phrases.create(k)
    end
    return key_phrases
  end
end

Я знаю, чего хочучтобы сделать, но из-за того, что мне не хватает знаний о Ruby и Rails, я не знаю точно, как это кодировать.

Ответы [ 2 ]

3 голосов
/ 28 октября 2019

Технически вы можете добавить псевдоним, чтобы убедиться, что остальная часть кода не нарушается. Идея состоит в том, чтобы переименовать существующий метод has_many во что-то другое и использовать существующий key_phrases в качестве обычного метода.

Таким образом, вам не нужно ничего менять в кодовой базе, и это будет работать с минимальными изменениями.

Подробнее о alias_attribute читайте здесь

class Metric < ApplicationRecord

  alias_attribute :phrases, :key_phrases #NOTE the alias_attribute should be before `key_phrases`
  has_many key_phrases

  def key_phrases
    # your logic goes into this method
    if phrases.empty?
      # create
    else
      phrases
    end
  end 
end

Однако ... Я лично создаю более полный метод и оставляю "has_many key_phrases" как есть,причина в том, что это подразумевает и получает, и если вы пытаетесь создать записи одним и тем же методом, это немного сбивает с толку.

Итак, я бы сделал что-то подобное

class Metric < ApplicationRecord

  has_many key_phrases

  def get_or_create_key_phrases(*params)
    if phrases.empty?
      # create
    else
      phrases
    end
  end 
end

, а затем изменил бывсе места, которые называют key_phrases до get_or_create_key_phrases, что я лично считаю более явным. Но в соответствии с недостатком, вам придется изменить больше мест в коде.

1 голос
/ 28 октября 2019

Вместо перезаписи метода получения для key_phrases, вы можете вместо этого написать обратный вызов, который создает key_phrases для объекта Metric после его создания.

def Metric < ApplicationRecord
  has_many key_phrases

  after_create do |metric|
    get_key_phrases.each do |phrase|
      metric.key_phrases.create(phrase)
    end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...