Skip to content

Instantly share code, notes, and snippets.

@astery
Last active August 29, 2015 14:21
Show Gist options
  • Save astery/b7db699ad4775291dadb to your computer and use it in GitHub Desktop.
Save astery/b7db699ad4775291dadb to your computer and use it in GitHub Desktop.
class SaleFilterForm
include ActiveModel::Model
include Virtus.model(nullify_blank: true)
attribute :from_price, Integer
attribute :to_price, Integer
attribute :from_year, Integer
attribute :to_year, Integer
attribute :with_images, Boolean, default: false
attribute :model_id, Integer
attribute :body_type_ids, Array[Integer]
validates :model_id, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, allow_nil: true
validate :check_model_existence
def fetch
SalesByFilter.new(self).fetch
end
private
def valid?
super &&
YearRange.new(from_year, to_year).valid? &&
PriceRange.new(from_price, to_price).valid?
end
def check_model_existence
if model_id.present?
errors.add(:model_id, 'такой модели не существует') unless Model.exists?(model_id)
end
end
end
class SalesByFilter
delegate ':price and etc..', to: :filter_model
def initlialize(filter_model)
@filter_model = filter_model
end
def fetch
sales_scope.merge(automobiles_scope)
end
def sales_scope
scope = Sale.joins(:automobile)
if scope_by_price?
price_range = PriceRange.new(from_price, to_price)
scope.price_between(price_range)
end
scope
end
def automobiles_scope
scope = Automobile.all
scope = scope.for_model(model_id) if scope_by_model?
if scope_by_year?
year_range = YearRange.new(from_year, to_year)
scope.year_between(year_range)
end
scope.with_images(with_images)
end
def scope_by_model?
model_id.present?
end
def scope_by_price?
from_price.present? || to_price.present?
end
def scope_by_year?
from_year.present? || to_year.present?
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment