Skip to main content
Version: v2.0

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 }
info

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

warning

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