+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
class ArvadosBase < ActiveRecord::Base
self.abstract_class = true
attr_accessor :attribute_sortkey
'modified_by_client_uuid' => '203',
'uuid' => '999',
}
+ @loaded_attributes = {}
end
def self.columns
- return @columns unless @columns.nil?
+ return @columns if @columns.andand.any?
@columns = []
@attribute_info ||= {}
schema = arvados_api_client.discovery[:schemas][self.to_s.to_sym]
@columns << column(k, :text)
serialize k, coldef[:type].constantize
end
+ define_method k do
+ unless new_record? or @loaded_attributes.include? k.to_s
+ Rails.logger.debug "BUG: access non-loaded attribute #{k}"
+ # We should...
+ # raise ActiveModel::MissingAttributeError, "missing attribute: #{k}"
+ end
+ super()
+ end
@attribute_info[k] = coldef
end
end
ArvadosResourceList.new(self).limit(*args)
end
+ def self.select(*args)
+ ArvadosResourceList.new(self).select(*args)
+ end
+
+ def self.with_count(*args)
+ ArvadosResourceList.new(self).with_count(*args)
+ end
+
+ def self.distinct(*args)
+ ArvadosResourceList.new(self).distinct(*args)
+ end
+
+ def self.include_trash(*args)
+ ArvadosResourceList.new(self).include_trash(*args)
+ end
+
+ def self.recursive(*args)
+ ArvadosResourceList.new(self).recursive(*args)
+ end
+
def self.eager(*args)
ArvadosResourceList.new(self).eager(*args)
end
- def self.all(*args)
- ArvadosResourceList.new(self).all(*args)
+ def self.all
+ ArvadosResourceList.new(self)
end
def self.permit_attribute_params raw_params
def save
obdata = {}
self.class.columns.each do |col|
- obdata[col.name.to_sym] = self.send(col.name.to_sym)
+ # Non-nil serialized values must be sent because we can't tell
+ # whether they've changed. Other than that, any given attribute
+ # is either unchanged (in which case there's no need to send its
+ # old value in the update/create command) or has been added to
+ # #changed by ActiveRecord's #attr= method.
+ if changed.include? col.name or
+ (self.class.serialized_attributes.include? col.name and
+ @loaded_attributes[col.name])
+ obdata[col.name.to_sym] = self.send col.name
+ end
end
obdata.delete :id
postdata = { self.class.to_s.underscore => obdata }
end
end
+ changes_applied
@new_record = false
self
hash = arvados_api_client.api(self.class, '/' + uuid_or_hash)
end
hash.each do |k,v|
+ @loaded_attributes[k.to_s] = true
if self.respond_to?(k.to_s + '=')
self.send(k.to_s + '=', v)
else
end
end
@all_links = nil
+ changes_applied
@new_record = false
self
end
self.class.to_s.underscore.humanize
end
+ def self.class_for_display
+ self.to_s.underscore.humanize
+ end
+
+ # Array of strings that are names of attributes that should be rendered as textile.
+ def textile_attributes
+ []
+ end
+
def self.creatable?
- current_user
+ current_user.andand.is_active && api_exists?(:create)
end
def self.goes_in_projects?
false
end
+ # can this class of object be copied into a project?
+ # override to false on indivudal model classes for which this should not be true
+ def self.copies_to_projects?
+ self.goes_in_projects?
+ end
+
def editable?
(current_user and current_user.is_active and
(current_user.is_admin or
current_user.uuid == self.owner_uuid or
new_record? or
- (writable_by.include? current_user.uuid rescue false)))
+ (respond_to?(:writable_by) ?
+ writable_by.include?(current_user.uuid) :
+ (ArvadosBase.find(owner_uuid).writable_by.include? current_user.uuid rescue false)))) or false
+ end
+
+ def deletable?
+ editable?
+ end
+
+ def self.api_exists?(method)
+ arvados_api_client.discovery[:resources][self.to_s.underscore.pluralize.to_sym].andand[:methods].andand[method]
+ end
+
+ # Array of strings that are the names of attributes that can be edited
+ # with X-Editable.
+ def editable_attributes
+ self.class.columns.map(&:name) -
+ %w(created_at modified_at modified_by_user_uuid modified_by_client_uuid updated_at)
end
def attribute_editable?(attr, ever=nil)
- if "created_at modified_at modified_by_user_uuid modified_by_client_uuid updated_at".index(attr.to_s)
+ if not editable_attributes.include?(attr.to_s)
false
elsif not (current_user.andand.is_active)
false
self.class.to_s.underscore
end
- def friendly_link_name
+ def friendly_link_name lookup=nil
(name if self.respond_to? :name) || default_name
end