This project is archived and is in readonly mode.
[PATCH] define_schema for Active Resource
Reported by Taryn East | December 18th, 2009 @ 03:17 PM | in 3.0.2
Ok, so Josh suggested I make a ticket for this for better tracking.
I've built some baseline functionality for defining a schema for an Active Resource.
Code available as a patch here: http://pastie.org/743842
and a more-readable combined diff here: http://pastie.org/743843
What you can now do is this:
class FlickrPhoto << ActiveResource::Base
define_schema do |s|
s.string :photo, :title
s.integer :width, :height
s.float :some_other_attribute
s.attribute 'and_another', 'string'
end
validates_presence_of :photo
validates_numericality_of :width, :height
end
# this works my_photo = FlickrPhoto.new(:photo => 'photo_stream_here', :title => 'eben', :tags => ['cat']) my_photo.valid? # => true my_photo.save # => true my_photo.photo # 'photo_stream_here'
# and now, so does this: new_photo = FlickrPhoto.new() new_photo.respond_to? :photo # => true new_photo.photo # => nil new_photo.valid? # => false
new_photo.known_attributes # => ['photo', 'title', 'height', 'width', 'some_other_attribute', 'and_another']
# and if you fetch and existing one: a_photo = FlickrPhoto.find(1) # abcdef123<instance_attribute>456</instance_attribute> a_photo.photo # => 'abcdef' a_photo.width # => '123' # note: still a string a_photo.instance_attribute # => '456' # note: also a string
a_photo.known_attributes # => ['photo', 'title', 'height', 'width', 'some_other_attribute', 'and_another', 'instance_attribute']
new_photo.respond_to? 'instance_attribute' # => false (because it's not a known_attribute)
More details on what/how in the rdoc for define_schema :)
To summarise:
1) You can define a schema using 'define_schema' and passing a block, or passing a hash to 'schema='
2) this populates a set of 'known_attributes' that are added to the list of attributes currently on an instance (if there's no schema, this means that the known_attributes equals the existing attributes on the instance - as it always has done).
3) known attributes will return 'true' to a 'respond_to?' and will not cause a 'NoMethodError' if invoked
4) it will also store the 'attribute type' against each attribute - currently this does nothing... but my next step is to add a typecast based on this, along with "attributes_before_typecast" ala Active Record. This will be extremely useful for integer values as I've found my own code peppered with "to_i" checks for attributes that I already know are meant to be integers :P
5) an extension will also allow us to pass in options. The only sensible one that I can see so far is ":default => 'blah') which will, of course, set up known attributes with their given defaults - unless otherwise specified.
This functionality follows from the original discussion-thread
here:
http://groups.google.com/group/rubyonrails-core/browse_thread/threa...
and then here:
http://groups.google.com/group/rubyonrails-core/browse_thread/threa...
Future extensions:
1) using 'instance_eval' to get rid of the 'do |s|' syntax
2) Making the attribute-type actually do something useful (in this
case: automatically typecast returned values as described
above)
3) adding the 'default' option that will auto-populate the
so-specified attributes on initialize
Comments and changes to this ticket
-
josh December 18th, 2009 @ 03:20 PM
- Milestone cleared.
- State changed from new to open
- Assigned user set to josh
-
josh December 21st, 2009 @ 01:06 AM
- State changed from open to committed
Committed.
Open a new ticket for any follow up patches. Also don't use pastie, it truncates your patch.
-
Andrea Campi October 11th, 2010 @ 07:25 AM
- Tag changed from activeresource, patched, schema to activeresource, patch, schema
- Importance changed from to Medium
bulk tags cleanup
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>