Skip to content

Instantly share code, notes, and snippets.

@andreapavoni
Created July 6, 2010 12:04
Show Gist options
  • Save andreapavoni/465303 to your computer and use it in GitHub Desktop.
Save andreapavoni/465303 to your computer and use it in GitHub Desktop.
Rails 3: An improved Search agnostic model using Arel
class RealtyRequestController < ApplicationController
#... other actions ...
def search
@s = Search.new(RealtyRequest,params[:search]) do |s|
s.contract_id :eq # value to search defaults to params[:search][:contract_id]
s.price_max :lteq # same here
s.price_min :gteq
s.zone :matches, "%#{params[:search][:zone]}%" # here I look for '%param%'
s.province :matches, "%#{params[:search][:province]}%"
s.municipality :matches, "%#{params[:search][:municipality]}%"
s.rooms :eq
s.mq :eq
end
@realty_requests = @s.result # assing result
@realty_requests.order(:created_at) # add order option
# ... other rendering stuff ...
end
end
class Search
attr_accessor :attributes
def initialize(model, attrs = {})
@attributes = {}
@model = model
@arel = model.arel_table
model.columns.each do |field|
pattr = field.name
attrs = Hash[attrs.select {|k,v| !v.empty? }]
searchable = !attrs[pattr].nil?
@attributes[pattr.to_sym] = attrs[pattr] if searchable
self.class.send(:define_method,field.name) do |cond, *value|
attr = field.name.to_sym
value = value.first || @attributes[attr] || nil
@model = @model.where(@arel[attr].send(cond,value)) if searchable
end
end
if block_given?
yield self
end
end
def result
@model
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment