1

我有一個模型(以下簡化版本 - 完整版有lot更多字段),我想在其上進行搜索。動態確定Rails模型屬性

class Media < ActiveRecord::Base 

    attr_accessible :subject, :title, :ref_code 

    validates :title, :presence => true 
    validates :subject, :presence => true 

    def self.search(terms_hash) 
    return if terms_hash.blank? 

    composed_scope = self.scoped 

    terms_hash.each_pair do |key, value| 
    if self.respond_to? key and not value.is_blank? 
     value.split(' ').each do |term| 
     term = "%#{term}%" 
     composed_scope = composed_scope.where("#{key} LIKE ?", term) 
     end 
    end 
    composed_scope 
    end 
end 

由於高級搜索表單幾乎是相同的用於創建模型/更新實例的形式,我希望創建一個動態看起來通過請求的PARAMS列表和匹配表單域模型的方法屬性通過名稱。因此,如果搜索請求是,

/search?utf8=✓&ref_code=111&title=test&subject=code&commit=Search 

然後我的控制器可以只調用Media.search(PARAMS),它會返回將搜索適當的值(一個或多個)的相應字段的作用域。正如你可以看到我嘗試使用respond_to?,但只是實例而不是實際模型類定義的,我需要忽略任何與模型無關的參數(例如utf8和在這種情況下提交)。如果這一切運作良好,我計劃重構代碼,以便我可以在多個模型中重複使用相同的方法。

是否有類似於respond_to?的類方法?你將如何去做同樣的任務?

我知道這是關係到get model attribute dynamically in rails 3但它並沒有真正回答什麼,我試圖做的,因爲我想這樣做對的模式而不是模型的實例。

回答

5

上有ActiveRecord的模型類一個columns method這樣你就可以輕鬆獲得的屬性名稱的列表:

names = Model.columns.map(&:name) 

你可以刪除一些常見的容易不夠:

names = Model.columns.map(&:name) - %w[id created_at updated_at] 

accessible_attributes類方法也可能是有趣的,它會告訴你什麼已經給了attr_accessible

+0

謝謝。列方法非常適合我的需求! 我總是很難找到我在API中需要的東西,因爲所有東西都分佈在很多類和模塊中。 – richard

+1

快速更新: 我也偶然發現了'columns_hash',它使用列名作爲鍵和與'columns'的值相同的信息。 – richard