Reputation: 1585
I have a model (simplified version below - the full one has a lot more fields) on which I want to do a search.
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
Since the advanced search form is almost identical to the form used to create/update instances of the model, I want to create a method that dynamically looks through the params list of the request and matches form fields to model attributes via the name. So if the search request was,
/search?utf8=✓&ref_code=111&title=test&subject=code&commit=Search
then my controller could just call Media.search(params) and it would return a scope that would search the appropriate fields for the appropriate value(s). As you can see I tried using respond_to?
but that is only defined for instances of the model rather than the actual model class and I need something that ignores any params not related to the model (eg. utf8 and commit in this case). If this all works well, I plan to refactor the code so that I can reuse the same method for multiple models.
Is there a class method similar to respond_to?
? How would you go about the same task?
I know this is related to get model attribute dynamically in rails 3 but it doesn't really answer what I'm trying to do because I want to do it on the the model rather than an instance of the model.
Upvotes: 1
Views: 731
Reputation: 434935
There is a columns
method on ActiveRecord model classes so you can easily get a list of attribute names:
names = Model.columns.map(&:name)
You could remove a few common ones easily enough:
names = Model.columns.map(&:name) - %w[id created_at updated_at]
The accessible_attributes
class method might also be of interest, that will tell you what has been given to attr_accessible
.
Upvotes: 5