每个问题都有一系列标签。
schema.rb:
create_table "questions", force: true do |t|
t.text "tags", default: [], array: true
如何以原子方式附加到标签?
如何防止阵列中的重复?
我试过question.update_attribute tags: tags << :ruby
,但这不起作用。
Rails 4.17和Postgres。
编辑:这似乎已在Rails 4.2中修复
答案 0 :(得分:2)
我认为update_attribute
不会有用,因为它会用新值替换数组而不是附加到它(但请参阅下面--Update--部分中的更好解释)。
我不确定这里有什么最佳做法,但这应该可以添加一些东西,如果它还没有:
question.tags << :ruby unless question.tags.include?(:ruby)
question.save
我会在Question模型上编写一个自定义方法来管理添加标记和检查唯一性:
def add_tag(tag)
if tags.include?(tag)
# do whatever you want to do when tag isn't unique
p "#{tag} is already in tags!"
else
tags << tag
save
end
end
然后使用question.add_tag(:ruby)
调用它。
--------------------更新-----------------------
如果这不起作用,可能会出现ActiveRecord无法识别字段已更改的问题(虽然它似乎在Rails 4.2中正常工作)。
这些链接解释了这个问题:
New data not persisting to Rails array column on Postgres
http://paweljaniak.co.za/2013/07/28/rails-4-and-postgres-arrays/
正如他们解释的那样,你可以在这里使用update_attribute
,但你需要替换整个数组,而不是将值推到它上面,如下所示:
question.update_attribute(:tags, question.tags << tag)
您还应该能够强制ActiveRecord考虑更新属性,方法是包括will_change!
,如下所示:
def add_tag(tag)
if tags.include?(tag)
# do whatever you want to do when tag isn't unique
p "#{tag} is already in tags!"
else
tags_will_change!
tags << tag
save
end
end