2016-01-12 66 views
0

我有一個ActiveRecord類,它的屬性是一個數組(Postgres數組列),我希望數組中的項目是唯一的。覆蓋陣列本身發生的方法的最好方法是什麼?例如#< <?重寫ActiveRecord屬性的append方法(<<)

module PgTags 

    def tags=(value) 
    write_attribute :tags, value.uniq 
    end 

end 

class Rule < ActiveRecord::Base 
    include PgTags 
end 

r = Rule.new 
r.tags = %w(one two one) 
puts r.tags # outputs ['one', 'two'] 
r.tags << 'one' 
puts r.tags # should still output ['one', 'two'] 
+0

你使用的是什麼版本的ActiveRecord? –

回答

2

當你寫r.tags << value你也可以看到像這樣r.tags.<<(value)tags方法將返回Array的實例,然後會發生這種情況:array.<<(value)該陣列將收到<<方法,而不是tags屬性。

您必須覆蓋Array上的<<方法。

最好是退回到r對象,並將add_tags方法添加到Rule以實現您提出的邏輯。什麼你問的是可能的,但更復雜的比這來實現:

module PgTags 
    def tags=(value) 
    write_attribute :tags, value.uniq 
    end 

    def add_tags(*t) 
    self.tags = (tags << t).flatten.uniq 
    end 
end 

class Rule < ActiveRecord::Base 
    include PgTags 
end 

r = Rule.new 
r.tags = %w(one two one) 
puts r.tags #=> ['one', 'two'] 
r.tags.add_tags 'one' 
r.tags.add_tags 'three' 
puts r.tags #=> ['one', 'two', 'three'] 

add_tags方法的行爲就像當你使用<<但它處理uniq的邏輯和分配新的值給你所期望規則自己的tags屬性。

0

一種不同的方法(現在我看到這是Postgres的)將這樣的:

class Rule < ActiveRecord::Base 
    before_validation :ensure_tags_unique 

    private 
    def ensure_tags_unique 
    self.tags = self.tags.uniq 
    end 
end 

這樣可以使內置AR的<<=功能。

+0

不,PostgreSQL支持標準的SQL數組列,AR也是如此,沒有涉及到'serialize' kludge。 –

+0

@ muistooshort我錯過了提到Postgres數組列的問題的一部分。現在我學到了關於ActiveRecord的新內容 - 謝謝! –

相關問題