Skip to content

Instantly share code, notes, and snippets.

@adz
Forked from joakimk/example.rb
Last active January 1, 2016 23:19
Show Gist options
  • Save adz/8215768 to your computer and use it in GitHub Desktop.
Save adz/8215768 to your computer and use it in GitHub Desktop.
class Filter
include FormObject
# Proc because Date.yesterday changes every day :)
attribute :from, Date, default: Proc.new { Date.yesterday }
attribute :to, Date, default: Proc.new { 1.month.from_now - 1.day }
end
# in controller
@filter = Filter.new(params[:filter])
@orders = Orders.between(@filter.from, @filter.to)
# in view
@filter.from # always a date, either a user entered date or the default date
# Ensures values are *written* as either the type you expect, a default value or nil.
#
# Virtus is built to handle data from a database where it's either well formed or nil. We need
# to tweak it's return values a little bit for it to handle form data. See https://github.com/solnic/virtus/issues/99.
module FormObject
include Virtus.model
module ClassMethods
def attribute(name, type, opts = {})
super(name, type, opts)
define_method("#{name}=") do |value|
value_after_coercion = super(value)
attribute = attribute_set[name]
if attribute.value_coerced?(value_after_coercion)
value_after_coercion
else
reset_attribute(name)
end
end
end
end
def self.included(descendant)
super
descendant.extend FormObject::ClassMethods
end
end
require 'spec_helper'
require 'form_object'
class Filter
include FormObject
attribute :from, Date, default: Proc.new { Date.yesterday }
attribute :number, Integer
end
describe FormObject do
it "can handle data from a form" do
filter = Filter.new(from: "2012-01-15")
filter.from.should be_kind_of(Date)
filter.from.should == Date.parse("2012-01-15")
end
it "defaults" do
filter = Filter.new
filter.from.should == Date.yesterday
end
it "defaults when it can't parse a value" do
filter = Filter.new(from: "2012-01-55")
filter.from.should == Date.yesterday
end
it "returns nil when it can't parse the value and there is no default" do
filter = Filter.new(number: "2012-01-55")
filter.number.should be_nil
end
it "returns nil when there is no default" do
filter = Filter.new
filter.number.should be_nil
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment