Skip to content

Attribute value from super implementation? #250

Closed
nybblr opened this Issue Feb 24, 2014 · 6 comments

3 participants

@nybblr
nybblr commented Feb 24, 2014

I have a REST based adapter for a User resource. When you ask it for user.created_at, it queries the API if necessary and returns the value. It also handles user.created_at=.

I'd like like to add Virtus on top of the setter/getter I have defined so I can coerce attributes coming from the JSON API (in this case, to a Date) -- is there anyway to do this? It seems like Virtus just creates its own ivars, but I'd like for it to use the get/set interface I've defined as the source.

Thanks!
~ Jonathan

@elskwid
Collaborator
elskwid commented Feb 24, 2014

@nybblr, it sounds like you aren't using Virtus already. If you only want to coerce that single attribute, perhaps you could just use Coercible in your object.

@nybblr
nybblr commented Feb 24, 2014

Thanks @elskwid, that looks pretty close to what I need. I have several other fields (~20) that need it too so I was hoping it would save me the tedium.

@elskwid
Collaborator
elskwid commented Feb 24, 2014

Ah, well, you didn't say that in your issue. 😉

We've recently used Virtus to do exactly what you describe. What we did was actually wire up Virtus to use a symbol for the default which makes it use a method. It might require some renaming on your part but it might work. I'm sure @solnic would have some ideas as well. (Something else to keep your eye on is Morpher. It is crazy powerful but lacking in documentation at the moment so you'll have to dig around the specs.

Here's an example of what we did in that project of ours:

class Product
  attribute :description, String,   default: :_description
  attribute :category,    [String], default: :_category
  attribute :color,       String,   default: :_color

  def _description
    row[:"description"]
  end

  def _category
    if row[:"categories"].present?
      row[:"categories"].split(",").map(&:strip)
    end
  end

  def _color
    row[:"item color"]
  end
end

Shortly after doing a bunch of these we saw the pattern and did something like this:

class Product
  include Connections
  include Row

  connect_attributes do
    description, "description", String
    category,    "categories",  [String]
    color,       "item color",  String
  end

  def _categories
    row_hash[:"categories"].split(",").map(&:strip)
  end
end
@solnic
Owner
solnic commented Feb 24, 2014

I would use a proxy object that would wrap "plain" virtus objects and handle lazy-loading through API there.

I think I have another mission for 2014 - un-active-recordify your minds ;)

@elskwid
Collaborator
elskwid commented Feb 24, 2014

I would like to say that the examples above don't touch an API. The API data gets handed to them, this is an example of how we handled wiring up Virtus for lots of attributes.

See what you did @solnic? You made me all defensive.

@solnic
Owner
solnic commented Jul 24, 2014

I'm closing this one as it doesn't seem like there's anything we could do in virtus' itself.

@solnic solnic closed this Jul 24, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.