首页 文章

如何在数组字段中使用Rails #update_attribute?

提问于
浏览
1

每个问题都有一系列标签 .

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中修复

1 回答

  • 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
    

相关问题