Merge branch 'master' into 1971-show-image-thumbnails
[arvados.git] / apps / workbench / app / models / arvados_base.rb
index 5c7e44f136b3417a8a4f9fa4db1a0d5bf1142b35..55932213445febe52f3b17587e5fe274e24ea3c0 100644 (file)
@@ -32,9 +32,7 @@ class ArvadosBase < ActiveRecord::Base
       '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'
@@ -45,50 +43,78 @@ 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
+
   def self.column(name, sql_type = nil, default = nil, null = true)
     ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
   end
+
   def self.attribute_info
     self.columns
     @attribute_info
   end
-  def self.find(uuid)
+
+  def self.find(uuid, opts={})
     if uuid.class != String or uuid.length < 27 then
       raise 'argument to find() must be a uuid string. Acceptable formats: warehouse locator or string with format xxxxx-xxxxx-xxxxxxxxxxxxxxx'
     end
-    new.private_reload(uuid)
+
+    # 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}"
+    if opts[:cache] == false
+      Rails.cache.write cache_key, $arvados_api_client.api(self, '/' + uuid)
+    end
+    hash = Rails.cache.fetch cache_key do
+      $arvados_api_client.api(self, '/' + uuid)
+    end
+    new.private_reload(hash)
   end
+
   def self.order(*args)
     ArvadosResourceList.new(self).order(*args)
   end
+
+  def self.filter(*args)
+    ArvadosResourceList.new(self).filter(*args)
+  end
+
   def self.where(*args)
     ArvadosResourceList.new(self).where(*args)
   end
+
   def self.limit(*args)
     ArvadosResourceList.new(self).limit(*args)
   end
+
   def self.eager(*args)
     ArvadosResourceList.new(self).eager(*args)
   end
+
   def self.all(*args)
     ArvadosResourceList.new(self).all(*args)
   end
+
   def save
     obdata = {}
     self.class.columns.each do |col|
@@ -118,8 +144,11 @@ class ArvadosBase < ActiveRecord::Base
       end
     end
 
+    @new_record = false
+
     self
   end
+
   def save!
     self.save or raise Exception.new("Save failed")
   end
@@ -133,14 +162,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|
@@ -159,6 +186,7 @@ class ArvadosBase < ActiveRecord::Base
     @links = $arvados_api_client.api Link, '', { _method: 'GET', where: o, eager: true }
     @links = $arvados_api_client.unpack_api_response(@links)
   end
+
   def all_links
     return @all_links if @all_links
     res = $arvados_api_client.api Link, '', {
@@ -171,9 +199,11 @@ class ArvadosBase < ActiveRecord::Base
     }
     @all_links = $arvados_api_client.unpack_api_response(res)
   end
+
   def reload
     private_reload(self.uuid)
   end
+
   def private_reload(uuid_or_hash)
     raise "No such object" if !uuid_or_hash
     if uuid_or_hash.is_a? Hash
@@ -196,8 +226,14 @@ class ArvadosBase < ActiveRecord::Base
       end
     end
     @all_links = nil
+    @new_record = false
     self
   end
+
+  def to_param
+    uuid
+  end
+
   def dup
     super.forget_uuid!
   end
@@ -262,9 +298,11 @@ class ArvadosBase < ActiveRecord::Base
   end
 
   def friendly_link_name
-    if self.class.column_names.include? 'name'
-      self.name
-    end
+    (name if self.respond_to? :name) || uuid
+  end
+
+  def selection_label
+    friendly_link_name
   end
 
   protected