2016-07-06 13 views
0

Я использую Rails 4 и имею модель Article, которая имеет answer, side_effects и benefits в качестве атрибутов.Интерполяция ключа атрибута перед сохранением

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

Вместо того, чтобы писать два практически одинаковых метода, один для побочных эффектов и один для преимуществ, я хотел бы использовать тот же метод и проверить, чтобы атрибут не был равен answer.

До сих пор у меня есть что-то вроде этого:

before_save :link_to_article 

private 

def link_to_article 
    self.attributes.each do |key, value| 
    unless key == "answer" 
     linked_attrs = [] 
     self.key.split(';').each do |i| 
     a = Article.where('lower(specific) = ?', i.downcase.strip).first 
     if a && a.approved? 
      linked_attrs.push("<a href='/questions/#{a.slug}' target=_blank>#{i.strip}</a>") 
     else 
      linked_attrs.push(i.strip) 
     end 
     end 
     self.key = linked_attrs.join('; ') 
    end 
    end 
end 

, но сцепление на ключе, как это дает мне undefined method 'key'.

Как я могу использовать интерполяцию в атрибуте?

ответ

1

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

вы можете использовать: self.send(key) вместо этого, но это может быть немного опасно. Если кто-то взломает новую форму в своем браузере, чтобы отправить вам атрибут delete!, вы не хотите, чтобы его случайно вызывали с помощью send, поэтому было бы лучше использовать read_attribute и write_attribute.

Пример ниже:

def link_to_article 
    self.attributes.each do |key, value| 
    unless key == "answer" 
     linked_attrs = [] 
     self.read_attribute(key).split(';').each do |i| 
     a = Article.where('lower(specific) = ?', i.downcase.strip).first 
     if a && a.approved? 
      linked_attrs.push("<a href='/questions/#{a.slug}' target=_blank>#{i.strip}</a>") 
     else 
      linked_attrs.push(i.strip) 
     end 
     end 
     self.write_attribute(key, linked_attrs.join('; ')) 
    end 
    end 
end 

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


OLD (прежде, чем я знал, что это должно было быть использовано на всех атрибутов)

Это сказал ... почему вы идете через каждый атрибут и только что-то делать, если атрибут называется answer? почему бы просто не беспокоиться о том, чтобы пройти через атрибуты и посмотреть прямо на ответ?

например:

def link_to_article 
    linked_attrs = [] 
    self.answer.split(';').each do |i| 
    a = Article.where('lower(specific) = ?', i.downcase.strip).first 
    if a && a.approved? 
     linked_attrs.push("<a href='/questions/#{a.slug}' target=_blank>#{i.strip}</a>") 
    else 
     linked_attrs.push(i.strip) 
    end 
    end 
    self.answer = linked_attrs.join('; ') 
end 
+1

То есть именно то, что мне нужно .. спасибо очень много. И я хотел бы выполнить этот метод по всем атрибутам, отличным от ответа ... вот почему я зацикливаюсь. Thx снова! @Taryn – Kathan

+0

ah cool right - это было непонятно из приведенного кода. Рад, что это помогло :) –

+0

Еще один вопрос для вас, прежде чем я приму ответ ... как я могу присвоить атрибутам новое значение? 'self.send (key) =" new value "' не работает. – Kathan

 Смежные вопросы

  • Нет связанных вопросов^_^