【问题标题】:Rails string array and PostgreSQLRails 字符串数组和 PostgreSQL
【发布时间】:2013-01-01 09:54:46
【问题描述】:

我有一个名为 Container 的 Rails 模型,其中有一列名为 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 方法有什么问题。有人可以对这种奇怪的情况有所了解吗?为什么我通过这个方法传值没有设置?

【问题讨论】:

  • “postgre”是指“PostgreSQL”吗?
  • 这不是很明显吗?不明白评论的价值。编辑过的标题,不过如此。
  • 不,不明显。评论的价值是为了澄清。 “PostgreSQL”是 DBM 的名称,有时缩写为“Postgres”,因为人们不喜欢说出整个名称。 (团队承认它很笨拙。)“Postgre”可能是那个或其他的,因为 StackOverflow 会收到来自世界各地用户的问题,而且他们并不总是拼写好或知道正确的名称。

标签: ruby-on-rails ruby rails-postgresql postgres-ext


【解决方案1】:

这个问题实际上是由使用&lt;&lt; 引起的。 Rails 不会跟踪对属性的修改 (see this issue)。我在the usage notes 中概述了在使用数组时要避免使用&lt;&lt; 运算符,因为rails 不会看到这种变化,它实际上会导致默认值出现问题。

这也可以通过检查products_changed? 状态来查看。当你使用&lt;&lt;时它会是假的。

【讨论】:

    【解决方案2】:

    这与 Ruby 赋值会创建局部变量这一事实有关,除非您明确声明接收者,在本例中为 self。所以:

    products = [product.id]
    

    ...将创建一个名为products 的局部变量。鉴于:

    self.products = [product.id]
    

    ...是您真正想要的。

    【讨论】:

    • 虽然说得通,但 self.products 并没有真正解决问题。
    • @papdel 你重启服务器了吗?您是否在add_to_products 方法中添加了调试代码?如果不是,那么您应该这样做,因为看起来那里的某些事情并没有像您期望的那样发生。所以调试它。只是盯着代码没有帮助。隔离问题。 logger.debug 是你的朋友。您也可能想阅读:guides.rubyonrails.org/debugging_rails_applications.html
    • 这是由于在 Rails 中跟踪属性更改的方式。更多详情见我的回答
    • 谢谢丹,我通过不同的路线绕过它,但这正是我想要的。
    猜你喜欢
    • 2014-12-11
    • 2012-04-04
    • 1970-01-01
    • 2022-11-24
    • 2017-03-04
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多