class Asset < ActiveRecord::Base
belongs_to :account
belongs_to :asset_type
belongs_to :deal_type
belongs_to :neighborhood
belongs_to :settlement
belongs_to :user
named_scope :showeb, :conditions => {:showeb => 2}
named_scope :ordered, :order => 'created_at DESC'
named_scope :demo, :conditions => {:demo => 1}
named_scope :image144, :conditions => ["image_list != ?", "null"]
named_scope :slideshow, :conditions => ["slideshow != ?", "null"]
named_scope :status, :conditions => {:status => 2}
named_scope :price_from, lambda {|*args| {:conditions => ["price_shekel >=?", (args.first || 0)]} }
named_scope :price_to, lambda {|*args| {:conditions => ["price_shekel <=?", (args.first || 9999999999)]} }
named_scope :rooms_from, lambda {|*args| {:conditions => ["rooms >=?", (args.first || 0)]} }
named_scope :rooms_to, lambda {|*args| {:conditions => ["rooms <=?", (args.first || 9999)]} }
named_scope :settlement_filter, lambda { |settlement_ids| {:conditions => {:settlement_id => settlement_ids.to_i} } }
named_scope :neighborhood_filter, lambda { |neighborhood_ids| {:conditions => ["neighborhood_id = ?", neighborhood_ids]} }
named_scope :assettype_filter, lambda { |assettype_ids| {:conditions => ["assettype_id = ?", assettype_ids]} }
named_scope :dealtype_filter, lambda { |dealtype_ids| {:conditions => ["dealtype_id = ?", dealtype_ids]} }
def self.search(asset_params, page, records)
main = showeb.ordered.demo.image144.slideshow.status
if asset_params
#asset_params = User input from advanced search form
settlement_conditions = settlement_filter(asset_params[:settlement_id]) if asset_params[:settlement_id]
neighborhood_conditions = neighborhood_filter(asset_params[:neighborhood_id]) if asset_params[:neighborhood_id]
assettype_conditions = assettype_filter(asset_params[:assettype_id]) if asset_params[:assettype_id]
dealtype_conditions = dealtype_filter(asset_params[:dealtype_id]) if asset_params[:dealtype_id]
price_from_conditions = price_from(asset_params[:pr_from]) if asset_params[:pr_from]
price_to_conditions = price_to(asset_params[:pr_to]) if asset_params[:pr_to]
rooms_from_conditions = rooms_from(asset_params[:rm_from]) if asset_params[:rm_from]
rooms_to_conditions = rooms_to(asset_params[:rm_to]) if asset_params[:rm_to]
<[Join all relevant named scopes according to User input ]>
main.< insert relevant named scopes >.paginate(:all, :page => page, :per_page => records)
else
main.paginate(:all, :page => page, :per_page => records)
end
end
end
Refactorings
No refactoring yet !
Marc-Andre
March 17, 2009, March 17, 2009 15:45, permalink
I'd use a naming convention, so that a parameter 'xyz' corresponds to a named_scope 'xyz_form_filter', for instance.
I didn't include any error checking, you'll get a NoMethodError thrown if the right form filter doesn't exist.
This gives:
class Asset < ActiveRecord::Base
belongs_to :account
belongs_to :asset_type
belongs_to :deal_type
belongs_to :neighborhood
belongs_to :settlement
belongs_to :user
named_scope :showeb, :conditions => {:showeb => 2}
named_scope :ordered, :order => 'created_at DESC'
named_scope :demo, :conditions => {:demo => 1}
named_scope :image144, :conditions => ["image_list != ?", "null"]
named_scope :slideshow, :conditions => ["slideshow != ?", "null"]
named_scope :status, :conditions => {:status => 2}
named_scope :pr_from_form_filter, lambda {|*args| {:conditions => ["price_shekel >=?", (args.first || 0)]} }
named_scope :pr_to_form_filter, lambda {|*args| {:conditions => ["price_shekel <=?", (args.first || 9999999999)]} }
named_scope :rm_from_form_filter, lambda {|*args| {:conditions => ["rooms >=?", (args.first || 0)]} }
named_scope :rm_to_form_filter, lambda {|*args| {:conditions => ["rooms <=?", (args.first || 9999)]} }
named_scope :settlement_id_form_filter, lambda { |settlement_ids| {:conditions => {:settlement_id => settlement_ids.to_i} } }
named_scope :neighborhood_id_form_filter, lambda { |neighborhood_ids| {:conditions => ["neighborhood_id = ?", neighborhood_ids]} }
named_scope :assettype_id_form_filter, lambda { |assettype_ids| {:conditions => ["assettype_id = ?", assettype_ids]} }
named_scope :dealtype_id_form_filter, lambda { |dealtype_ids| {:conditions => ["dealtype_id = ?", dealtype_ids]} }
def self.search(asset_params, page, records)
main = showeb.ordered.demo.image144.slideshow.status
asset_params.each do |key, value|
main = main.send(:"#{key.to_s}_form_filter", value)
end if asset_params
main.paginate(:all, :page => page, :per_page => records)
end
end
Erez Ben Shoham
March 17, 2009, March 17, 2009 21:18, permalink
Hi Andre,
Thanks for your code
I found on Ryan Bates railscasts.com this
http://railscasts.com/episodes/112-anonymous-scopes
class Asset < ActiveRecord::Base
belongs_to :account
belongs_to :asset_type
belongs_to :deal_type
belongs_to :neighborhood
belongs_to :settlement
belongs_to :user
named_scope :showeb, :conditions => {:showeb => 2}
named_scope :ordered, :order => 'created_at DESC'
named_scope :demo, :conditions => {:demo => 1}
named_scope :image144, :conditions => ["image_list != ?", "null"]
named_scope :slideshow, :conditions => ["slideshow != ?", "null"]
named_scope :status, :conditions => {:status => 2}
named_scope :group_settlements, :group => :settlement_id
named_scope :group_neighborhoods, :group => :neighborhood_id
named_scope :group_assettypes, :group => :assettype_id
def self.search(asset_params, page, records)
if asset_params
scope = scoped({})
scope = scope.conditions "settlement_id = ?", asset_params[:settlement_id] unless asset_params[:settlement_id].blank?
scope = scope.conditions "neighborhood_id = ?", asset_params[:neighborhood_id] unless asset_params[:neighborhood_id].blank?
scope = scope.conditions "assettype_id = ?", asset_params[:assettype_id] unless asset_params[:assettype_id].blank?
scope = scope.conditions "dealtype_id = ?", asset_params[:dealtype_id] unless asset_params[:dealtype_id].blank?
scope = scope.conditions "price_shekel >= ?", asset_params[:pr_from] unless asset_params[:pr_from].blank?
scope = scope.conditions "price_shekel <= ?", asset_params[:pr_to] unless asset_params[:pr_to].blank?
scope = scope.conditions "rooms >= ?", asset_params[:rm_from] unless asset_params[:rm_from].blank?
scope = scope.conditions "rooms <= ?", asset_params[:rm_to] unless asset_params[:rm_to].blank?
scope.showeb.ordered.demo.image144.slideshow.status.paginate(:all, :page => page, :per_page => records)
else
showeb.ordered.demo.image144.slideshow.status.paginate(:all, :page => page, :per_page => records)
end
end
# file - /config/initializers/global_named_scopes.rb
class ActiveRecord::Base
named_scope :conditions, lambda { |*args| {:conditions => args} }
end
Tj Holowaychuk
March 18, 2009, March 18, 2009 00:58, permalink
Like @Marc mentioned its almost always a good practice to utilize names that you have been using programmatically already, it will bite you in the ass if you dont normalize these things, and prevent a lot of automation
I have an Asset model in a Real Estate app
What is the best way to join all named_scope(asset_params) (lines
27..34) to line 36
Thanks
Erez