Dynamometer
Adds dynamic attributes to ActiveRecord models
Usage
Generate a migration to enable hstore
class EnableHstore < ActiveRecord::Migration
def up
enable_extension "hstore"
end
def down
disable_extension "hstore"
end
end
Add a dynamic_attributes hstore when creating a table
create_table :users do |t|
t.hstore :dynamic_attributes
t.index :dynamic_attributes
end
or add dynamic_attributes to an existing table
add_column :users, :dynamic_attributes, :hstore
add_index :users, :dynamic_attributes
Add dynamic attributes to your ActiveRecord model
class User < ActiveRecord::Base
include DynamicAttributes
end
Accessors
You can read dynamic attributes like you would typical attributes.
user.category
user[:category]
user['category']
You can write dynamic attributes like you would typical attributes, as well.
user.category = 'superuser'
user[:category] = 'superuser'
user['category'] = 'superuser'
user.update_attribute(:category, 'superuser')
user.update_attributes(category: 'superuser')
Dynamic attributes will appear in your model's attributes user.attributes
as if they were typical database attributes.
You can access just the dynamic attributes by calling dynamic_attributes
.
Validating
You can validate dynamic attributes if you declare them in your model:
class Person < ActiveRecord::Base
include DynamicAttributes
dynamic_attributes :hometown
validates_length_of :hometown, minimum: 2, allow_nil: true
end
Attempting to validate undeclared dynamic attributes will fail with NoMethodError if the attribute hasn't been set at all; don't do that.
Querying
You can query for matches to dynamic attributes just like regular attributes.
current_site.users.where(category: 'superuser')
current_site.users.where(category: 'superuser', name: 'Steve')
You can also query for matches to dynamic attributes by calling
where_dynamic_attributes
. Unlike where
above, this will not work if you
mix dynamic and regular attributes.
current_site.users.where_dynamic_attributes(category: 'superuser')
ActiveModel Serializers
If you want to serialize all of your dynamic attributes using activemodel serializers
class UserSerializer < ActiveModel::Serializer
include DynamicAttributesSerializer
attributes :id
end
Strong Parameters
To specify that dynamic attributes should be allowed using strong parameters,
include the PermitDynamic
concern in your controller and specify the model
to be checked against.
class PeopleController < ApplicationController
include PermitDynamic
def create
@person = Person.create(person_params)
render json: @person
end
private
def person_params
params.require(:person).permit(:name, dynamic_attributes: Person)
end
end
This will permit any parameters that are NOT valid regular attributes of Person
.
Installation
Add this line to your application's Gemfile:
gem 'dynamometer'
And then execute:
$ bundle