【问题标题】:How to use Rails #update_attribute with array field?如何使用带有数组字段的 Rails #update_attribute?
【发布时间】:2015-06-17 07:42:08
【问题描述】:

每个问题都有一组标签。

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

【问题讨论】:

    标签: ruby-on-rails ruby postgresql ruby-on-rails-4 activerecord


    【解决方案1】:

    我不认为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 &lt;&lt; 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
    

    【讨论】:

    • 这个方法其实我写的。但由于某种原因它不起作用。显然 ActiveRecord 无法从模型中更新数组字段。但是,它确实可以通过控制器工作。
    • 嗯,不知道问题出在哪里——你是在问题对象还是模型类上调用它?我在 Rails 控制台中对一个对象进行了快速测试,它似乎有效。我描绘的用例是在控制器中调用的模型上的实例方法,例如:question = Question.find(params[:id] 然后类似于question.add_tag(params[:tag])
    • 我在问题对象上调用了它。 question.add_tag 对你有用吗?我想可能还有其他事情发生,因为add_tag 中的代码在控制器中有效,但在对象上调用add_tag 时无效。这很奇怪,因为在对象上调用 add_tag 时可以更新其他字段。
    • 另外一个奇怪的是save方法返回true,但是记录没有更新。所以我认为 ActiveRecord 和数组字段存在问题。
    • 我有一个 Rack 应用程序,而不是 Rails。所以这是一个可能的原因。 self.tags &lt;&lt; tag; save 并且不会更新标签字段。它将更新其他字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多