在保存之前插入属性的键
Interpolating an attribute's key before save
我正在使用 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'
.
如何在属性中进行插值?
在这一点中: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
我正在使用 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'
.
如何在属性中进行插值?
在这一点中: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