2013-06-20 62 views
1

我有兩個方法是相同的除了他們引用ActiveRecord類:導軌 - 動態方法創建

def category_id_find(category_name) 
    category = Category.find_by_name(category_name) 
    if category != nil 
    return category.id 
    else 
    return nil 
    end 
end 

def brand_id_find(brand) 
    brand = Brand.find_by_name(brand) 
    if brand != nil 
    return brand.id 
    else 
    return nil 
    end 
end 

現在,我只知道必須有一個更Railsy /紅寶石去這組合成一些種動態創建的方法,它有兩個參數,類和查找的字符串,所以我嘗試(和失敗的)像這樣的東西:

def id_find(class, to_find) 
    thing = (class.capitalize).find_by_name(to_find) 
    if thing.id != nil 
    return thing.id 
    else 
    return nil 
    end 
end 

,這意味着我可以打電話給id_find(category, "Sports")

我必須從單個包含所有數據的怪獸CSV文件播種期間填充表格。因此,例如,我必須抓取CSV中所有不同的類別,將它們放在類別表中,然後根據來自剛剛填充的類別表的ID分配每個項目的category_id,如果這樣做有道理的話......

回答

1

class是保留關鍵字i n Ruby(它只用於類聲明),所以你不能用它來命名你的方法參數。開發人員經常將其更改爲klass,這保留了原始含義而不會與此限制相沖突。但是,在這種情況下,您可能會將一個類的名稱作爲字符串傳遞,所以我將其稱爲class_name

Rails的ActiveSupport有一些內置的變形方法,可以用來將字符串變成常量。根據你的CSV數據的樣子,你可能最終得到這樣的:

def id_find(class_name, to_find) 
    thing = (class_name.camelize.constantize).find_by_name(to_find) 
    ... 
end 
+0

constantize - 我gogole福必須路要走 - 正是我一直在尋找 - 謝謝! – BenjiBoyWick

0

如果使用字符串,則可以使用constantize,而不是利用你的代碼,就可以(在理論上):

thing = passed_in_class.constantize.find_by_name(to_find) 

但你也可以通過實際的類本身的方法,沒有理由不爲:

thing = passed_in_class.find_by_name(to_find)