class Osm::Model

This class is expected to be inherited from. It provides the caching and permission handling for model objects.

Constants

SORT_BY

Public Class Methods

configure(options) click to toggle source

Configure the options used by all models @param [Hash] options @option options [Class, nil] :cache An instance of a cache class, must provide the methods (exist?, delete, write, read), for details see Rails.cache. Set to nil to disable caching. @option options [Fixnum] :ttl (optional, default = 1800 (30 minutes)) The default TTL value for the cache, note that some items are cached for twice this time and others are cached for half this time (in seconds) @option options [String] :prepend_to_key (optional, default = 'OSMAPI') Text to prepend to the key used to store data in the cache @return nil

# File lib/osm/model.rb, line 27
def self.configure(options)
  raise ArgumentError, ":ttl must be a FixNum greater than 0" if options[:ttl] && !(options[:ttl].is_a?(Fixnum) && options[:ttl] > 0)
  raise ArgumentError, ":prepend_to_key must be a String" if options[:prepend_to_key] && !options[:prepend_to_key].is_a?(String)
  if options[:cache]
    [:exist?, :delete, :write, :read].each do |method|
      raise ArgumentError, ":cache must have a #{method} method" unless options[:cache].methods.include?(method)
    end
  end

  @@cache = options[:cache]
  @@cache_prepend = options[:prepend_to_key] || 'OSMAPI'
  @@cache_ttl = options[:ttl] || 600
  nil
end

Private Class Methods

api_has_permission?(api, to, on, section, options={}) click to toggle source

Check if the user has granted the relevant permission to the API @param [Osm::Api] api The api to use to make the request @param [Symbol] to What action is required to be done (e.g. :read or :write) @param [Symbol] on What the OSM permission is required on (e.g. :member or :programme) @param [Osm::Section, Fixnum, to_i] section The Section (or its ID) the permission is required on @!macro options_get

# File lib/osm/model.rb, line 183
def self.api_has_permission?(api, to, on, section, options={})
  access = Osm::ApiAccess.get_ours(api, section, options)
  return false if access.nil?
  (access.permissions[on] || []).include?(to)
end
cache_delete(api, key) click to toggle source
# File lib/osm/model.rb, line 112
def self.cache_delete(api, key)
  return true if @@cache.nil?
  @@cache.delete(cache_key(api, key))
end
cache_exist?(api, key) click to toggle source
# File lib/osm/model.rb, line 108
def self.cache_exist?(api, key)
  return false if @@cache.nil?
  @@cache.exist?(cache_key(api, key))
end
cache_key(api, key) click to toggle source
# File lib/osm/model.rb, line 116
def self.cache_key(api, key)
  key = key.join('-') if key.is_a?(Array)
  "#{@@cache_prepend.empty? ? '' : "#{@@cache_prepend}-"}#{Osm::VERSION}-#{api.site}-#{key}"
end
cache_read(api, key) click to toggle source

Wrap cache calls

# File lib/osm/model.rb, line 99
def self.cache_read(api, key)
  return nil if @@cache.nil?
  @@cache.read(cache_key(api, key))
end
cache_write(api, key, data, options={}) click to toggle source
# File lib/osm/model.rb, line 103
def self.cache_write(api, key, data, options={})
  return false if @@cache.nil?
  options.reverse_merge!(expires_in: @@cache_ttl)
  @@cache.write(cache_key(api, key), data, options)
end
can_access_section?(api, section, options={}) click to toggle source

Check if the user has access to a section @param [Osm::Api] api The api to use to make the request @param [Osm::Section, Fixnum, to_i] section The Section (or its ID) the permission is required on @!macro options_get

# File lib/osm/model.rb, line 146
def self.can_access_section?(api, section, options={})
  api.get_user_permissions(options).keys.include?(section.to_i)
end
get_from_ids(api, ids, key, arguments=[], options, get_all_method) click to toggle source

Get a list of items given a list of item IDs @param [Osm::Api] api The api to use to make the request @param [Array<Fixnum>] ids The ids of the items to get @param [String] key The key for getting an item from the cache (the key [key, id] is generated) @param [Array] argumentss The arguments to pass to get_all @!macro options_get @param [Symbol] get_all_method The method to get all items (either :get_all or :get_for_section) @return [Array] An array of the items

# File lib/osm/model.rb, line 246
def self.get_from_ids(api, ids, key, arguments=[], options, get_all_method)
  raise ArgumentError, "get_all_method is invalid" unless [:get_all, :get_for_section].include?(get_all_method)
  items = Array.new
  ids.each do |id|
    if cache_exist?(api, [key, id])
      items.push cache_read(api, [*key, id])
    else
      # At least this one item is not in the cache - we might as well refresh the lot
      return self.send(get_all_method, api, *arguments, options.merge(:no_cache => true))
    end
  end
  return items
end
has_access_to_section?(api, section, options={}) click to toggle source

Check if the user has access to a section @param [Osm::Api] api The api to use to make the request @param [Osm::Section, Fixnum, to_i] section The Section (or its ID) the $ @!macro options_get @return [Boolean] If the Api user has access the section

# File lib/osm/model.rb, line 127
def self.has_access_to_section?(api, section, options={})
  api.get_user_permissions(options).keys.include?(section.to_i)
end
has_permission?(api, to, on, section, options={}) click to toggle source

Check if the user has the relevant permission @param [Osm::Api] api The api to use to make the request @param [Symbol] to What action is required to be done (e.g. :read or :write) @param [Symbol] on What the OSM permission is required on (e.g. :member or :programme) @param [Osm::Section, Fixnum, to_i] section The Section (or its ID) the permission is required on @!macro options_get

# File lib/osm/model.rb, line 156
def self.has_permission?(api, to, on, section, options={})
  user_has_permission?(api, to, on, section, options) && api_has_permission?(api, to, on, section, options)
end
require_ability_to(api, to, on, section, options={}) click to toggle source

Raise an exception if the user does not have the relevant permission @param [Osm::Api] api The api to use to make the request @param [Symbol] to What action is required to be done (e.g. :read or :write) @param [Symbol] on What the OSM permission is required on (e.g. :member or :programme) @param [Osm::Section, Fixnum, to_i] section The Section (or its ID) the permission is required on @!macro options_get

# File lib/osm/model.rb, line 226
def self.require_ability_to(api, to, on, section, options={})
  section = Osm::Section.get(api, section, options) unless section.is_a?(Osm::Section)
  require_permission(api, to, on, section, options)
  if section.youth_section? && [:register, :contact, :events, :flexi].include?(on)
    require_subscription(api, :silver, section, options)
  end
  if section.youth_section? && [:finance].include?(on)
    require_subscription(api, :gold, section, options)
  end
end
require_access_to_section(api, section, options={}) click to toggle source

Raise an exception if the user does not have access to a section @param [Osm::Api] api The api to use to make the request @param [Osm::Section, Fixnum, to_i] section The Section (or its ID) the permission is required on @!macro options_get @raise [Osm::Forbidden] If the Api user can not access the section

# File lib/osm/model.rb, line 136
def self.require_access_to_section(api, section, options={})
  unless has_access_to_section?(api, section, options)
    raise Osm::Forbidden, "You do not have access to that section"
  end
end
require_permission(api, to, on, section, options={}) click to toggle source

Raise an exception if the user does not have the relevant permission @param [Osm::Api] api The api to use to make the request @param [Symbol] to What action is required to be done (e.g. :read or :write) @param [Symbol] on What the OSM permission is required on (e.g. :member or :programme) @param [Osm::Section, Fixnum, to_i] section The Section (or its ID) the permission is required on @!macro options_get @raise [Osm::Forbidden] If the Api user does not have the required permission

# File lib/osm/model.rb, line 196
def self.require_permission(api, to, on, section, options={})
  section = Osm::Section.get(api, section.to_i, options) unless section.is_a?(Osm::Section)
  section_name = section.try(:name)
  unless user_has_permission?(api, to, on, section, options)
    raise Osm::Forbidden, "Your OSM user does not have permission to #{to} on #{on} for #{section_name}."
  end
  unless api_has_permission?(api, to, on, section, options)
    raise Osm::Forbidden, "You have not granted the #{to} permissions on #{on} to the #{api.api_name} API for #{section_name}."
  end
end
require_subscription(api, level, section, options={}) click to toggle source

Raise an exception if the user does not have the relevant permission @param [Osm::Api] api The api to use to make the request @param [Symbol, Fixnum] level The OSM subscription level required (:bronze, :silver, :gold, :gold_plus) @param [Osm::Section, Fixnum, to_i] section The Section (or its ID) the subscription is required on @!macro options_get @raise [Osm::Forbidden] If the Section does not have the required OSM Subscription (or higher)

# File lib/osm/model.rb, line 213
def self.require_subscription(api, level, section, options={})
  section = Osm::Section.get(api, section, options) unless section.is_a?(Osm::Section)
  if section.nil? || !section.subscription_at_least?(level)
    raise Osm::Forbidden, "Insufficent OSM subscription level (#{Osm::SUBSCRIPTION_LEVEL_NAMES[level]} required for #{section.name})."
  end
end
user_has_permission?(api, to, on, section, options={}) click to toggle source

Check if the user has the relevant permission within OSM @param [Osm::Api] api The api to use to make the request @param [Symbol] to What action is required to be done (e.g. :read or :write) @param [Symbol] on What the OSM permission is required on (e.g. :member or :programme) @param [Osm::Section, Fixnum, to_i] section The Section (or its ID) the permission is required on @!macro options_get

# File lib/osm/model.rb, line 166
def self.user_has_permission?(api, to, on, section, options={})
  section_id = section.to_i
  permissions = api.get_user_permissions(options)
  permissions = permissions[section_id] || {}
  permissions = permissions[on] || []
  unless permissions.include?(to)
    return false
  end
  return true
end

Public Instance Methods

<(another) click to toggle source
# File lib/osm/model.rb, line 55
def <(another)
  send('<=>', another) < 0
end
<=(another) click to toggle source
# File lib/osm/model.rb, line 58
def <=(another)
  send('<=>', another) <= 0
end
<=>(another) click to toggle source

Compare functions

# File lib/osm/model.rb, line 49
def <=>(another)
  us_values = self.class::SORT_BY.map{ |i| self.try(i) }
  them_values = self.class::SORT_BY.map{ |i| another.try(i) }
  us_values <=> them_values
end
>(another) click to toggle source
# File lib/osm/model.rb, line 61
def >(another)
  send('<=>', another) > 0
end
>=(another) click to toggle source
# File lib/osm/model.rb, line 64
def >=(another)
  send('<=>', another) >= 0
end
between?(min, max) click to toggle source
# File lib/osm/model.rb, line 67
def between?(min, max)
  (send('<=>', min) > 0) && (send('<=>', max) < 0)
end
changed_attributes() click to toggle source

Get a list of attributes which have changed @return Array the names of attributes which have changed

# File lib/osm/model.rb, line 74
def changed_attributes
  attributes.keys.select{ |k| attributes[k] != @original_attributes[k] }
end
reset_changed_attributes() click to toggle source

Reset the list of attributes which have changed

# File lib/osm/model.rb, line 79
def reset_changed_attributes
  classes_to_clone = [Array, Hash]
  attributes_now = attributes.map do |k,v|
    [k, (classes_to_clone.include?(v.class) ? v.clone : v)]
  end # Deep(ish) clone
  @original_attributes = Hash[attributes_now]
end
to_i() click to toggle source

Default to_i conversion is of id

# File lib/osm/model.rb, line 44
def to_i
  id.to_i
end