Ленивая настройка атрибутов модели в Rails? - PullRequest
0 голосов
/ 16 апреля 2009

У меня есть модель, которая генерируется путем анализа файла данных. Существует несколько интересных значений, которые отсутствуют в исходном файле данных, но могут быть получены из следующих значений:

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

Я пытался это:

def profit
  if not self[:profit]
    update_attribute :profit, expensive_computation
  end
  self[:profit]
end

К сожалению, это только половина работы. Вычисленное значение сохраняется, но каждый раз, когда я называю прибыль, оно снова вычисляет значение.

UPDATE:

Оказывается, проблема была не в методе, а в ранее найденном операторе find_by_sql, в котором Rails запутался в идентификаторах моделей. Код, с которым я закончил, был таким:

def profit
  unless read_attribute(:profit)
    update_attribute(:profit, expensive_computation ) 
    self.save!
  end
  read_attribute(:profit)
end

Ответы [ 4 ]

2 голосов
/ 17 апреля 2009

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

 def update_profit
    update_attribute :profit, expensive_computation
 end

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

 @model.profit

Где @model - это экземпляр любого класса, в котором находится атрибут profit.

1 голос
/ 17 ноября 2011
def profit
  super || update_attribute(:profit, expensive_computation)
  return super
end

Если в столбце прибыли есть информация, просто вызовите оригинальный метод прибыли объекта, который вернет содержимое столбца profit из базы данных.

В противном случае (т. Е. Столбец profit имеет значение nil) используйте метод update_attribute, чтобы вычислить значение profit и сохранить его в базе данных, а затем просто вернуть значение из базы данных еще раз.

Если вы предпочитаете получить значение profit, если оно уже есть в базе данных, или просто true, если выполнялись дорогостоящие вычисления, просто сделайте это (update_attribute вернет true или false):

def profit
  super || update_attribute(:profit, expensive_computation)
end
0 голосов
/ 17 апреля 2009

Это прекрасно работает для меня. Моя первая мысль: у вас есть опечатка в строке if not self[:profit]?

0 голосов
/ 17 апреля 2009

Куда должен идти код, будет зависеть от того, когда можно рассчитать прибыль (например, как только запись будет впервые сохранена или будет иногда позже?), И может ли прибыль когда-либо измениться. 1001 *

В целом, вероятно, лучше поместить вычисление в какой-то вызов before_create / before_save, который сохраняет его только тогда, когда возможно вычислить и / или изменилось

vrish88 прав, что вы, вероятно, должны оставить метод profit в покое, если вам действительно не нужно вычислять это на лету, когда нужны данные. Если это действительно то, что вам нужно, попробуйте:

def profit
  update_attribute(:profit, expensive_computation) unless read_attribute(:profit)

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