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 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
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
# 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
# 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
# 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
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
# 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
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 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
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
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
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
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
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
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
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
# File lib/osm/model.rb, line 55 def <(another) send('<=>', another) < 0 end
# File lib/osm/model.rb, line 58 def <=(another) send('<=>', another) <= 0 end
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
# File lib/osm/model.rb, line 61 def >(another) send('<=>', another) > 0 end
# File lib/osm/model.rb, line 64 def >=(another) send('<=>', another) >= 0 end
# File lib/osm/model.rb, line 67 def between?(min, max) (send('<=>', min) > 0) && (send('<=>', max) < 0) end
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 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
Default to_i
conversion is of id
# File lib/osm/model.rb, line 44 def to_i id.to_i end