2

我有一个名为的 Rails 模型Container,其中有一列名为products. 它是 Postgres 和 'postgres_ext' gem 支持的字符串数组。

GEMFILE 的相关部分是:

gem 'rails', '3.2.9'
gem 'pg'
gem 'postgres_ext'
gem 'activerecord-postgres-hstore', git: 'git://github.com/engageis/activerecord-postgres-hstore.git'

迁移的相关部分是:

 t.string :products, array: true

我正在我的Container模型中编写一个公共方法,它将产品添加到这个数组中。该方法如下所示:

 attr_accessible :products

 def add_to_products(product)

  if products.blank? || products.size == 0 ## product array is either uninstantiated or blank
    products = [product.id]
  else  

    unless products.include? product.id
      products << product.id
    end
  end
end

这些是 irb/console 中的结果:

pry(main)> c = Container.first
=> #<Container id: "2765cc19-98f8-4e42-a1be-538788424ec7", name:....
pry(main)> p = Product.first
=> #<Product id: "319a25ae-87fe-4769-a9de-1a8e0db9e84f", name: ....
pry(main)> c.add_to_products(product)
pry(main)> c.products
=> nil
pry(main)> c.products= [] << "319a25ae-87fe-4769-a9de-1a8e0db9e84f"
pry(main)> c.products
=> ["319a25ae-87fe-4769-a9de-1a8e0db9e84f"]

我正在挠头,想弄清楚该add_to_products方法出了什么问题。有人可以对这种奇怪的情况有所了解吗?为什么通过此方法传递值时未设置值?

4

2 回答 2

5

这个问题实际上是由于使用<<. Rails 不会就地跟踪属性的修改(请参阅此问题)。我在使用说明中概述了在使用数组时要避免使用<<运算符,因为 rails 不会看到这种变化,它实际上会导致默认值出现问题。

通过检查products_changed?状态也可以看出这一点。使用时会为假<<

于 2013-02-04T15:23:30.143 回答
2

这与在 Ruby 赋值中创建局部变量这一事实有关,除非您明确声明接收者,self在这种情况下就是这样。所以:

products = [product.id]

...将创建一个名为products. 然而:

self.products = [product.id]

...是您真正想要的。

于 2013-01-01T12:28:41.827 回答