Properties
Restricting properties
Properties on a resource can be restricted for reading and or writing
Including specific properties
class User < ApplicationRecord
rhino_properties_read only: %i[id uid name email]
rhino_properties_create only: %i[name nickname email]
rhino_properties_update only: %i[name nickname]
end
Excluding specific properties
class User < ApplicationRecord
rhino_properties_read except: %i[password]
end
class User < ApplicationRecord
rhino_properties_write except: %i[email]
end
Restricting array operations
Array operations for nested properties can be limited by the rhino_properties_array
method. This can be used disallow creation, update or destruction of array items.
accepts_nested_attributes_for :og_meta_tags, allow_destroy: true
# Disallow creation of new og_meta_tags
rhino_properties_array og_meta_tags: { creatable: false, updatable: false, destroyable: false }
The allow_destroy
option for accepts_nested_attributes_for
must be set to true
for the destroyable
option to work. The allow_destroy
option is used for the destroyable
setting by default.
Overriding default settings
Specifying a format
A specific format can be set for a property. For example, a phone number can be of type string, but it can be formatted as a phone number in the front end.
rhino_properties_formats phone: :phone, blog_categories: :join_table_simple
Setting display name
The readable name is used to label the property in forms, display, filters and more in the front end. By default it is based on the name of the property in the backend. The readable name for one or more properties can be overridden:
rhino_properties_readable_name title: "Name", description: "Body"
File attachments
Files can be attached to ActiveRecord models with Active Storage and referenced by referring to the attachment relationship.
class BlogPost < ApplicationRecord
belongs_to :blog
has_one_attachment :header_image
rhino_owner :blog
rhino_references [:blog, :header_image_attachment]
end
or for many attachments:
class BlogPost < ApplicationRecord
belongs_to :blog
has_many_attachments :post_image
rhino_owner :blog
rhino_references [:blog, :post_image_attachments]
end
Tags
Rhino includes the acts_as_taggable gem for tagging support. Simply add the acts_as_taggable_on :tags
to your model and Rhino will automatically add the tags property to the resource.
class BlogPost < ApplicationRecord
belongs_to :blog
acts_as_taggable_on :tags
rhino_owner :blog
rhino_references %i[blog]
end
Trees
Working but not yet documented
Additional formats
Rhino provides additional backend helpers for common formats that can be used to validate the format of a property.
Country
Use the country validator based on countries gem for backend validation. Your model might look something like this:
# Validate the optional country
validates :country, country: { allow_blank: true }
# Validate the required alpha3 country
validates :country, country: { alpha3: true }
Currency
Use the field as currency in the front end. Your model might look something like this:
# Set the format for the attribute
rhino_properties_format amount: :currency
IPv4
Use the ipv4 validator for backend validation. Your model might look something like this:
# Validate the optional country
validates :ipv4, ipv4: { allow_blank: true }
Mac Address
Use the mac address validator for backend validation. Your model might look something like this:
# Validate the optional country
validates :mac_address, mac_address: { allow_blank: true }
Phone
Use phonelib for backend validation. It is built based on Google's libphonenumber which is the standard for this. Your model might look something like this:
# Set the format for the attribute
rhino_properties_format phone: :phone
# Normalize the phone number to e164 format
before_validation :normalize_phone
# Validate the phone number is possible (limited check)
validates :phone, phone: { message: "not a valid phone number", possible: true }
private
def normalize_phone
self.phone = Phonelib.parse(phone).full_e164.presence
end
Synthetic Attributes
At times you may need to "synthesize" an attribute that is not stored in the database. This is useful for attributes that are derived from other attributes or attributes that are not stored in the database but are needed for display or other purposes.
Because Rhino introspects the attributes for an ActiveRecord model in order to provide API responses, standard Rails techniques can be used to define synthetic attributes. For example, the following model defines a fahrenheit
attribute that is derived from the celsius
attribute which is stored in the database.
class Temperature < ApplicationRecord
attribute :fahrenheit, :float
rhino_owner_global
# Convert the celsius attribute to fahrenheit
def fahrenheit
celsius * 9 / 5 + 32
end
# Convert the passed in fahrenheit value to celsius and store it in the celsius attribute
def fahrenheit=
celsius = (fahrenheit - 32) * 5 / 9
end
validates :celsius, presence: true
end
Read only attributes
Its more common to have read only attributes of this type. The built in attr_readonly method can be used to mark the attribute as read only. This prevents the attribute from being updated or being set during creation.
class Temperature < ApplicationRecord
attribute :fahrenheit, :float
attr_readonly :fahrenheit
rhino_owner_global
def fahrenheit
celsius * 9 / 5 + 32
end
validates :celsius, presence: true
end
Property manipulations
All normal manipulations of properties are supported.
class Temperature < ApplicationRecord
attribute :fahrenheit, :float
rhino_owner_global
# Only fahrenheit to be set on update, not create
rhino_properties_create except: :fahrenheit
# Convert the celsius attribute to fahrenheit
def fahrenheit
celsius * 9 / 5 + 32
end
# Convert the passed in fahrenheit value to celsius and store it in the celsius attribute
def fahrenheit=
celsius = (fahrenheit - 32) * 5 / 9
end
validates :celsius, presence: true
end