Merge branch 'master' of git.clinicalfuture.com:arvados
[arvados.git] / apps / workbench / app / models / arvados_base.rb
index 4ba53b952992d043e8ee04fce98db7f307f84286..1a0da6424a828b0638aaf95305ffbcb5d34b8273 100644 (file)
@@ -25,19 +25,23 @@ class ArvadosBase < ActiveRecord::Base
     super(*args)
     @attribute_sortkey ||= {
       'id' => nil,
-      'uuid' => '000',
-      'owner_uuid' => '001',
-      'created_at' => '002',
-      'modified_at' => '003',
-      'modified_by_user_uuid' => '004',
-      'modified_by_client_uuid' => '005',
-      'name' => '050',
-      'tail_kind' => '100',
-      'tail_uuid' => '100',
-      'head_kind' => '101',
-      'head_uuid' => '101',
-      'info' => 'zzz-000',
-      'updated_at' => 'zzz-999'
+      'name' => '000',
+      'owner_uuid' => '002',
+      'event_type' => '100',
+      'link_class' => '100',
+      'group_class' => '100',
+      'tail_uuid' => '101',
+      'head_uuid' => '102',
+      'object_uuid' => '102',
+      'summary' => '104',
+      'description' => '104',
+      'properties' => '150',
+      'info' => '150',
+      'created_at' => '200',
+      'modified_at' => '201',
+      'modified_by_user_uuid' => '202',
+      'modified_by_client_uuid' => '203',
+      'uuid' => '999',
     }
   end
 
@@ -45,20 +49,25 @@ class ArvadosBase < ActiveRecord::Base
     return @columns unless @columns.nil?
     @columns = []
     @attribute_info ||= {}
-    return @columns if $arvados_api_client.arvados_schema[self.to_s.to_sym].nil?
-    $arvados_api_client.arvados_schema[self.to_s.to_sym].each do |coldef|
-      k = coldef[:name].to_sym
-      if coldef[:type] == coldef[:type].downcase
-        @columns << column(k, coldef[:type].to_sym)
+    schema = $arvados_api_client.discovery[:schemas][self.to_s.to_sym]
+    return @columns if schema.nil?
+    schema[:properties].each do |k, coldef|
+      case k
+      when :etag, :kind
+        attr_reader k
       else
-        @columns << column(k, :text)
-        serialize k, coldef[:type].constantize
+        if coldef[:type] == coldef[:type].downcase
+          # boolean, integer, etc.
+          @columns << column(k, coldef[:type].to_sym)
+        else
+          # Hash, Array
+          @columns << column(k, :text)
+          serialize k, coldef[:type].constantize
+        end
+        attr_accessible k
+        @attribute_info[k] = coldef
       end
-      attr_accessible k
-      @attribute_info[k] = coldef
     end
-    attr_reader :etag
-    attr_reader :kind
     @columns
   end
 
@@ -76,6 +85,11 @@ class ArvadosBase < ActiveRecord::Base
       raise 'argument to find() must be a uuid string. Acceptable formats: warehouse locator or string with format xxxxx-xxxxx-xxxxxxxxxxxxxxx'
     end
 
+    if self == ArvadosBase
+      # Determine type from uuid and defer to the appropriate subclass.
+      return resource_class_for_uuid(uuid).find(uuid, opts)
+    end
+
     # Only do one lookup on the API side per {class, uuid, workbench
     # request} unless {cache: false} is given via opts.
     cache_key = "request_#{Thread.current.object_id}_#{self.to_s}_#{uuid}"
@@ -132,12 +146,10 @@ class ArvadosBase < ActiveRecord::Base
     @etag = resp[:etag]
     @kind = resp[:kind]
 
-    # these attrs can be modified by "save" -- we should update our copies
-    %w(uuid owner_uuid created_at
-       modified_at modified_by_user_uuid modified_by_client_uuid
-      ).each do |attr|
+    # attributes can be modified during "save" -- we should update our copies
+    resp.keys.each do |attr|
       if self.respond_to? "#{attr}=".to_sym
-        self.send(attr + '=', resp[attr.to_sym])
+        self.send(attr.to_s + '=', resp[attr.to_sym])
       end
     end
 
@@ -159,14 +171,12 @@ class ArvadosBase < ActiveRecord::Base
       true
     end
   end
-      
+
   def links(*args)
     o = {}
     o.merge!(args.pop) if args[-1].is_a? Hash
     o[:link_class] ||= args.shift
     o[:name] ||= args.shift
-    o[:head_kind] ||= args.shift
-    o[:tail_kind] = self.kind
     o[:tail_uuid] = self.uuid
     if all_links
       return all_links.select do |m|
@@ -245,6 +255,10 @@ class ArvadosBase < ActiveRecord::Base
     }
   end
 
+  def class_for_display
+    self.class.to_s
+  end
+
   def self.creatable?
     current_user
   end
@@ -252,7 +266,8 @@ class ArvadosBase < ActiveRecord::Base
   def editable?
     (current_user and current_user.is_active and
      (current_user.is_admin or
-      current_user.uuid == self.owner_uuid))
+      current_user.uuid == self.owner_uuid or
+      new_record?))
   end
 
   def attribute_editable?(attr)
@@ -263,7 +278,9 @@ class ArvadosBase < ActiveRecord::Base
     elsif "uuid owner_uuid".index(attr.to_s) or current_user.is_admin
       current_user.is_admin
     else
-      current_user.uuid == self.owner_uuid or current_user.uuid == self.uuid
+      current_user.uuid == self.owner_uuid or
+        current_user.uuid == self.uuid or
+        new_record?
     end
   end
 
@@ -300,6 +317,10 @@ class ArvadosBase < ActiveRecord::Base
     (name if self.respond_to? :name) || uuid
   end
 
+  def content_summary
+    self.class_for_display
+  end
+
   def selection_label
     friendly_link_name
   end