Attributes
All Futures stands on the shoulders of two giants, Active Entity and Kredis.
Active Entity presents a "virtual model" that is backed by Redis instead of a relational database. By implementing Active Model, an All Futures model should be useful everywhere that you might usually use an Active Record model in your Rails app.
Instead of creating migrations, All Futures model attributes are declared in the class using the attribute
method. At minimum, you must specify a Symbol parameter for the name.
You can specify attributes with the following types: :string
, :text
, :integer
, :float
, :decimal
, :datetime
, :date
, :time
, and :boolean
.
Attributes will automatically be :string
type unless you pass a second Symbol parameter.
Optionally, you can define a default
value, as well as flag an attribute as an array
. Other types have their own special options, such as Decimal
. Unfortunately, the limit
and null
options are disregarded.
So far as I can tell, :text
is a :string
and :time
is a :datetime
. While you can specify type :binary
, Active Entity gets a bit salty, throwing an Encoding::UndefinedConversionError
exception when you attempt to save.
Aggregations
Active Model classes include a composed_of
method which provides model instances with dynamic methods that map attributes to complex classes.
For example, you could map an address to an Address
class:
And then you can call these getters and setters to access the members of the Address
class:
You can learn more in the Rails Guide.
Arrays
When defining an Array, it's good practice to make sure that your default
value is an empty Array. This is true with Postgres-backed Active Record migrations as well.
Decimal
The precision represents the total number of digits in the number, whereas scale represents the number of digits following the decimal point.
Enums
You can use the enum
class method to define a set of possible values for an attribute. It is similar to the enum
functionality in Active Model, but has significant enough quirks that you should think of them as distinct.
The first thing you'll notice about the :steve
attribute is that it is an "Integer", even though it might seem logical to define it as a String... TL;DR: don't do this. Even though the attribute is ultimately stored in Redis as a String, internally enum
tracks the possible values based on their index position in the array. It's also possible to provide a Hash of possible values:
The other quirk of this implementation is that you must create your attribute
before you call enum
.
enum
does not create the search scopes that might be familar to Active Model users, since there is no ActiveRecord::Relation
or scope concept in All Futures. You can, however, access the mapping directly to obtain the index number for a given value:
You can define prefixes and suffixes for your enum attributes. Note the underscores:
Kredis attributes
Kredis attributes can be used in an All Futures model in the exact same way they are used in Active Record models. The format follows a predictable pattern: kredis_datatype
:
This will create a new Redis key/value pair that is fully managed by Kredis, and accessed via the foo
accessor of your Example
instances. The kredis_counter
, kredis_unique_list
and kredis_slots
are all really useful tools.
You can set and retrieve values from Kredis attributes using the value
method:
All instances of your All Futures model will share the same Kredis attribute values. Advanced users can experiment with using a Proc to pass a unique value when the class is instantiated.
It's important to remember that Kredis attributes are not tracked as All Futures attributes, and they are stored in entirely different Redis keys.
Secure Passwords
All Futures models can store and authenticate secure passwords. You store the digest value in an attribute instead of using attr_accessor
.
You can now set values for the password
and password_confirmation
attributes. valid?
will return false
and the errors
accessor will contain an ActiveModel::Error
exception if the two values aren't present or don't match.
You can check to see if a password is valid using the authenticate(value)
method.
In order to use the secure password mechanism, your application must require the bcrypt
gem. If you use Devise, it's already in your project.
Last updated