Skip to content

Instantly share code, notes, and snippets.

@janx
Last active December 18, 2015 03:48
Show Gist options
  • Select an option

  • Save janx/5720374 to your computer and use it in GitHub Desktop.

Select an option

Save janx/5720374 to your computer and use it in GitHub Desktop.
Some thoughts on Virtus use in our project.

The more Virtus code I wrote, the more awkward I feel it is. It's not because Virtus is inherently bad, I just don't think it fits our case.

  1. So many attributes need to be marked reader: :private. It's not ruby's way. Ruby has its own private keyword.

  2. NilToDefault is bad. How do I decide whether a model need to include it? Or we simply include it everywhere?

  3. The difference between writer_class and default is subtle. Why does the implementer add a new writer_class here? Why does he use default value there? We're using different ways to do the same thing (compute values) here.

  4. writer_class is awkward. Why do I need to create a class just for its coerce method? I feel like writing Java.

  5. default method is the most awkward. We turn every computed attribute from a single method to two method (attribute and the default method) by using Virtus. There're dozens of attributes like beds below in ListingPresenter.

  6. The type annotation is useless.

module Listing
class Base
def initialize(attributes)
@attributes = attributes
end
def addressline1
@attributes['addressline1']
end
def agappointmentactive
@attributes['agappointmentactive'] == '1' ? true : false
end
def beds
format_range(@attributes['listingbedlow'], @attributes['listingbedhigh'])
end
def listingseopath
seo_path =~ %r{^/} ? seo_path : "/#{seo_path}"
end
end
end
module Listing
module Base
include Virtus
attribute :addressline1, String
attribute :agappointmentactive, Virtus::Attribute::Boolean
attribute :beds, String, default: :default_beds
attribute :listingbedhigh, Integer, reader: :private
attribute :listingbedlow, Integer, reader: :private
def default_beds
format_range(listingbedlow, listingbedhigh)
end
class SeoPathWriter < Virtus::Attribute::Writer::Coercible
# @param seo_path [String] Relative path from Endeca
# @return [String] Absolute path
def coerce(seo_path)
seo_path =~ %r{^/} ? seo_path : "/#{seo_path}"
end
end
attribute :listingseopath, String, writer_class: SeoPathWriter
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment