2013-05-10 75 views
0

Ruby的新手在這裏。首先,這比實際更具哲理性,所以如果有更好的方法來實現這一點,請告訴。遍歷數據庫記錄創建屬性哈希

我有一個表,看起來大致是:

╔════╦════════╦════════╦══════════╗ 
║ ID ║ label ║ value ║ thing_id ║ 
╠════╬════════╬════════╬══════════╣ 
║ 1 ║ color ║ red ║  1 ║ 
║ 2 ║ size ║ medium ║  1 ║ 
║ 3 ║ weight ║ heavy ║  1 ║ 
╚════╩════════╩════════╩══════════╝ 

我查詢此並獲得一個特定的事物的記錄。

thing_attributes = ThingAttributes.where(:thing_id => 1) 

這導致該表中有5行左右的記錄集。我希望能夠創建一個允許我創建{"color" => "red", "size" => "medium", "weight" => "heavy" }的等效項目。思考?

+0

你能澄清你的問題。我對你的措辭感到困惑。 – jason328 2013-05-10 19:50:31

+0

對不起。我認爲我的頭銜可能是錯誤的。我會盡力澄清。 – netricate 2013-05-10 19:58:18

+0

你想要這個散列究竟是什麼?每個記錄標籤的彙總?該表應該是一個統一的散列圖嗎?我的意思是,如果你有50條記錄,你想要一個有50個鍵和50個值的散列嗎?你會接受多個具有相同標籤(密鑰)的記錄嗎? – 2013-05-10 20:20:07

回答

2

好了,基本上你想模仿無模式數據庫,因爲您希望不同的記錄具有不同的屬性。只要你只有一個自定義屬性pr。記錄,這可能是工作,但如果你的記錄有差異比一般多個屬性,那麼你可能要考慮有多種型號,看看到hstore數據類型或尋找到一個文件數據庫,如MongoDB的。

更新

重讀你的問題,我想我有一個更好的解決辦法,所以我刪除了原來的一個。

我會打電話給你ThingAttributes類什麼,我認爲這是 - 一個CustomAttribute類。因爲每個記錄代表一個自定義屬性。事物可以有許多(在你的例子中是五個)自定義屬性。

所以,你可以這樣做:

class CustomAttribute < ActiveRecord::Base 
    belongs_to :thing 
    attr_accessible :name, :value 
end 

class Thing < ActiveRecord::Base 
    has_many :custom_attributes 
end 

現在你可以找到一個東西,寫

my_thing = Thing.find(3) 

然後你可以找到它的custom_attributes,通過寫

my_thing.custom_attributes 

這將返回一組自定義屬性。然而,你是(出於某種原因)要求散列。這也可以做到。在您的Thing類中,定義此方法:

def custom_attributes_hash 
    custom_hash = {} 
    self.custom_attributes.each do |attr| 
    custom_hash[attr.name] = attr.value 
    end 
    custom_hash 
end 

現在,您可能希望能夠以便捷的方式設置屬性。在你的課堂上定義這個。

def set_custom_attribute(name, value) 
    return unless name.present? # Short circuits method if an empty string or nil is being used as name. 
    custom_attribute = self.custom_attributes.find_by_name(name) # Attemps to find custom attribute with the name 
    if custom_attribute.nil? # Executes block if no attribute was found 
    return unless value.present? # Short circuits method if nil or empty string was passed as value 
    self.custom_attributes.create(name: name, value: value) # Creates and saves new custom attribute 
    else 
    if value.present? # Updates existing attribute if passed is not an empty string or nil. 
     custom_attribute.update_attribute(:value, value) 
    else 
     custom_attribute.destroy # Deletes custom attribute from DB if set_custom_attribute was called with a nil or empty value. 
    end 
    end 
end 
+0

這看起來像我應該做的。非常感謝!(特別是在我重讀了我的問題之後,真的很尷尬地問過它 - 你得到了我之後的結果) – netricate 2013-05-10 20:09:19

+0

我編輯了答案,因爲我忘記了Ruby不支持重載。你可以有一個attr方法,它既是一個getter也是一個setter(第二個參數是可選的),但它有一些缺陷。 – 2013-05-10 20:13:04

+0

我已經讀過你的問題了,我不認爲我的解決方案會起作用,因爲你不會得到你要求的散列。相反,您將獲得一組記錄,每個記錄都有自己的屬性。通過調用標籤訪問器,您將能夠確定該記錄的任何自定義屬性,但效果不佳。我會編輯一個更好的解決方案的答案。 – 2013-05-10 20:26:26

0

我不知道如果我越來越好,但試試這個:

my_thing = Thing.find(1) 
my_thing.color 
0

我覺得這是你在問什麼:

Thing_model.rb 

thing = Thing.find(1) 

def #{self.label} 
    return self.value