Class | AWS::Record::Base |
In: |
lib/aws/record/errors.rb
lib/aws/record/base.rb |
Parent: | Object |
An ActiveRecord-like interface built ontop of AWS.
class Book < AWS::Record::Base string_attr :title string_attr :author integer :number_of_pages timestamps # adds a :created_at and :updated_at pair of timestamps end b = Book.new(:title => 'My Book', :author => 'Me', :pages => 1) b.save
When extending AWS::Record::Base you should first consider what attributes your class should have. Unlike ActiveRecord, AWS::Record models are not backed by a database table/schema. You must choose what attributes (and what types) you need.
For more information about the various attribute macros available, and what options they accept, see {AttributeMacros}.
Normally you just call these methods inside your model class definition:
class Book < AWS::Record::Base string_attr :title boolean_attr :has_been_read integer_attr :number_of_pages float_attr :weight_in_pounds datetime_attr :published_at end
For each attribute macro a pair of setter/getter methods are added # to your class (and a few other useful methods).
b = Book.new b.title = "My Book" b.has_been_read = true b.number_of_pages = 1000 b.weight_in_pounds = 1.1 b.published_at = Time.now b.save b.id #=> "0aa894ca-8223-4d34-831e-e5134b2bb71c" b.attributes #=> { 'title' => 'My Book', 'has_been_read' => true, ... }
All attribute macros accept the +:default_value+ option. This sets a value that is populated onto all new instnaces of the class.
class Book < AWS::Record::Base string_attr :author, :deafult_value => 'Me' end Book.new.author #=> 'Me'
AWS::Record permits storing multiple values with a single attribute.
class Book < AWS::Record::Base string_attr :tags, :set => true end b = Book.new b.tags #=> #<Set: {}> b.tags = ['fiction', 'fantasy'] b.tags #=> #<Set: {'fiction', 'fantasy'}>
These multi-valued attributes are treated as sets, not arrays. This means:
Please consider these limitations when you choose to use the +:set+ option with the attribute macros.
It‘s important to validate models before there are persisted to keep your data clean. AWS::Record supports most of the ActiveRecord style validators.
class Book < AWS::Record::Base string_attr :title validates_presence_of :title end b = Book.new b.valid? #=> false b.errors.full_messages #=> ['Title may not be blank']
Validations are checked before saving a record. If any of the validators adds an error, the the save will fail.
For more information about the available validation methods see {Validations}.
You can find records by their ID. Each record gets a UUID when it is saved for the first time. You can use this ID to fetch the record at a latter time:
b = Book["0aa894ca-8223-4d34-831e-e5134b2bb71c"] b = Book.find("0aa894ca-8223-4d34-831e-e5134b2bb71c")
If you try to find a record by ID that has no data an error will be raised.
You can enumerate all of your records using all.
Book.all.each do |book| puts book.id end Book.find(:all) do |book| puts book.id end
Be careful when enumerating all. Depending on the number of records and number of attributes each record has, this can take a while, causing quite a few requests.
If you only want a single record, you should use first.
b = Book.first
Frequently you do not want ALL records or the very first record. You can pass options to find, all and first.
my_books = Book.find(:all, :where => 'owner = "Me"') book = Book.first(:where => { :has_been_read => false })
You can pass as find options:
More useful than writing query fragments all over the place is to name your most common conditions for reuse.
class Book < AWS::Record::Base scope :mine, where(:owner => 'Me') scope :unread, where(:has_been_read => false) scope :by_popularity, order(:score, :desc) scope :top_10, by_popularity.limit(10) end # The following expression returns 10 books that belong # to me, that are unread sorted by popularity. next_good_reads = Book.mine.unread.top_10
There are 3 standard scope methods:
Where accepts aruments in a number of forms:
Book.where('title = "My Book"')
Book.where('title = ?', 'My Book')
Book.where(:title => 'My Book')
This orders the records as returned by AWS. Default ordering is ascending. Pass the value :desc as a second argument to sort in reverse ordering.
Book.order(:title) # alphabetical ordering Book.order(:title, :desc) # reverse alphabetical ordering
You may only order by a single attribute. If you call order twice in the chain, the last call gets presedence:
Book.order(:title).order(:price)
In this example the books will be ordered by :price and the order(:title) is lost.
Just call limit with an integer argument. This sets the maximum number of records to retrieve:
Book.limit(2)
It should be noted that all finds are lazy (except first). This means the value returned is not an array of records, rather a handle to a {Scope} object that will return records when you enumerate over them.
This allows you to build an expression without making unecessary requests. In the following example no request is made until the call to each_with_index.
all_books = Books.all ten_books = all_books.limit(10) ten_books.each_with_index do |book,n| puts "#{n + 1} : #{book.title}" end
@return [Hash<String,Attribute>] Returns a hash of all of the
configured attributes for this class.
Constructs a new record for this class/domain.
@param [Hash] attributes A set of attribute values to seed this record
with. The attributes are bulk assigned.
@return [Base] Returns a new record that has not been persisted yet.
@return [AWS::SimpleDB::Domain] Returns a reference to the domain
this class will save data to.
@private
Allows you to override the default domain name for this record. The defualt domain name is the class name. @param [String] The domain name that should be used for this class.
@return [Hash] A hash with attribute names as hash keys (strings) and
attribute values (of mixed types) as hash values.
Persistence indicates if the record has been saved previously or not.
@example
@recipe = Recipe.new(:name => 'Buttermilk Pancackes') @recipe.persisted? #=> false @recipe.save! @recipe.persisted? #=> true
@return [Boolean] Returns true if this record has been persisted.
Creates new records, updates exsting records. If there is a validation error then an exception is raised. @raise [InvalidRecordError] Raised when the record has validation
errors and can not be saved.
@return [true] Returns true after a successful save.
Bulk assigns the attributes and then saves the record. @param [Hash] attribute_hash A hash of attribute names (keys) and
attribute values to assign to this record.
@return (see save)
Bulk assigns the attributes and then saves the record. Raises an exception (AWS::Record::InvalidRecordError) if the record is not valid. @param (see update_attributes) @return [true]
Returns the typecasted value for the named attribute.
book = Book.new(:title => 'My Book') book['title'] #=> 'My Book' book.title #=> 'My Book'
This method‘s primary use is for getting/setting the value for an attribute inside a custom method:
class Book < AWS::Record::Base string_attr :title def title self['title'] ? self['title'].upcase : nil end end book = Book.new(:title => 'My Book') book.title #=> 'MY BOOK'
@param [String,Symbol] attribute_name The name of the attribute to fetch
a value for.
@return The current type-casted value for the named attribute.
If you define a custom setter, you use #[]= to set the value on the record.
class Book < AWS::Record::Base string_attr :name # replace the default #author= method def author= name self['author'] = name.blank? ? 'Anonymous' : name end end
@param [String,Symbol] The attribute name to set a value for @param attribute_value The value to assign.