2013-01-01 14 views
2

我有一個名爲Container的Rails模型,其列名爲products。這是一個由Postgres和'postgres_ext'gem支持的字符串數組。Rails字符串數組和PostgreSQL

的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 /控制檯:

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方法。有人可以對這種奇怪的情況有所瞭解嗎?爲什麼當我通過這種方法傳遞值時沒有設置值?

+0

「postgre」,你的意思是「PostgreSQL」? –

+0

不是很明顯嗎?不明白評論的價值。編輯的標題,沒有更多。 – papdel

+0

不,這並不明顯。評論的價值是澄清。 「PostgreSQL」是DBM的名稱,有時縮寫爲「Postgres」,因爲人們不喜歡說出整個名稱。 (團隊承認它很笨拙。)「Postgre」可能是那個或其他的東西,因爲StackOverflow接收來自世界各地用戶的問題,並且他們並不總是拼寫得很好或者不知道正確的名字。 –

回答

5

這個問題實際上是由於使用<<而引起的。 Rails沒有跟蹤屬性的修改(see this issue)。我在the usage notes中概述了在使用數組時,您要避免使用<<運算符,因爲rails不會看到此更改,但實際上會導致使用默認值的問題。

這也可以通過檢查products_changed?狀態來看出。當您使用<<時這將是錯誤的。

1

這是因爲在Ruby分配中創建局部變量,除非您明確聲明接收者,在這種情況下爲self。所以:

products = [product.id] 

...將創建一個名爲products的局部變量。鑑於:

self.products = [product.id] 

...是你真正想要的。

+0

雖然這很有道理,但self.products並沒有真正解決問題。 – papdel

+0

@papdel你重新啓動了服務器嗎?你有沒有將調試代碼添加到你的'add_to_products'方法中?如果不是那麼你應該,因爲它看起來像沒有像你期望的事情發生。所以調試它。只是盯着代碼沒有幫助。隔離問題。 'logger.debug'是你的朋友。你也可以閱讀:http://guides.rubyonrails.org/debugging_rails_applications.html – Casper

+0

這是由於在rails中跟蹤屬性更改的方式。查看我的回答獲取更多詳情 –