2015-11-19 67 views
2

使用neo4j的Rails 4應用程序和使用carrierwave-neo4jneo4j.rb gem將圖像附加到Report對象。使用Neo4j的Carrierwave未將圖像關聯保存到DB

2.0.0-p353 :001 > r = Report.find_by(name: 'my new report') 
=> #<Report avatar: #<AvatarUploader:0x0000000643d950 @model=#<Report avatar: #<AvatarUploader:0x0000000643d950 ...>, created_at: Thu, 19 Nov 2015 14:25:58 +0000, created_by: nil, description: nil, embedJSON: nil, gridsize: nil, name: "my new report", tableau_link: nil, thumbnail_uri: nil, timestamp: nil, type: nil, updated_at: Thu, 19 Nov 2015 15:01:18 +0000, updated_by: nil>, @mounted_as=:avatar>, created_at: Thu, 19 Nov 2015 14:25:58 +0000, created_by: nil, description: nil, embedJSON: nil, gridsize: nil, name: "my new report", tableau_link: nil, thumbnail_uri: nil, timestamp: nil, type: nil, updated_at: Thu, 19 Nov 2015 15:01:18 +0000, updated_by: nil> 
2.0.0-p353 :002 > File.open('app/assets/images/nd-gray.png') { |f| r.avatar = f } 
=> #<File:app/assets/images/nd-gray.png (closed)> 
2.0.0-p353 :003 > r.avatar.url 
=> "/vagrant/fenrir/tmp/uploads/1447945541-17455-0224/nd-gray.png" 
2.0.0-p353 :004 > r.save 
=> true 
2.0.0-p353 :005 > r.avatar.url 
=> "/uploads/development/Report/nd-gray.png" 

在這一點上一切工作正常。但是,當我嘗試重新加載Report對象時,關聯就像它從未發生過一樣。

2.0.0-p353 :006 > r = Report.find_by(name: 'my new report') 
=> #<Report avatar: #<AvatarUploader:0x00000004205108 @model=#<Report avatar: #<AvatarUploader:0x00000004205108 ...>, created_at: Thu, 19 Nov 2015 14:25:58 +0000, created_by: nil, description: nil, embedJSON: nil, gridsize: nil, name: "my new report", tableau_link: nil, thumbnail_uri: nil, timestamp: nil, type: nil, updated_at: Thu, 19 Nov 2015 15:05:53 +0000, updated_by: nil>, @mounted_as=:avatar>, created_at: Thu, 19 Nov 2015 14:25:58 +0000, created_by: nil, description: nil, embedJSON: nil, gridsize: nil, name: "my new report", tableau_link: nil, thumbnail_uri: nil, timestamp: nil, type: nil, updated_at: Thu, 19 Nov 2015 15:05:53 +0000, updated_by: nil> 
2.0.0-p353 :007 > r.avatar.url 
=> nil 
2.0.0-p353 :007 > r.avatar.path 
=> nil 

切換到:aws上傳而不是:文件工作正常上傳,但具有相同的缺失關聯。

這是我的carrierwave類對象。

#app/uploaders/avatar_uploader.rb 
class AvatarUploader < CarrierWave::Uploader::Base 
    # Choose what kind of storage to use for this uploader: 
    storage :file 

    # Override the directory where uploaded files will be stored. 
    def store_dir 
    "uploads/#{Rails.env}/#{model.class}/" 
    end 

    # Add a white list of extensions which are allowed to be uploaded. 
    def extension_white_list 
    %w(jpg jpeg gif png) 
    end 
end 

而且carrierwave初始化

#config/initializers/carrierwave.rb 
CarrierWave.configure do |config| 
    config.storage = :file 
    config.aws_bucket = ENV['S3_BUCKET_NAME'] 
    config.aws_acl = 'private' 

    config.aws_credentials = { 
    access_key_id:  ENV['S3_KEY'], 
    secret_access_key: ENV['S3_SECRET'], 
    region:   ENV['S3_REGION'] # Required 
    } 

    # The maximum period for authenticated_urls is only 10 minutes. 
    # config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7 

    # # Set custom options such as cache control to leverage browser caching 
    # config.aws_attributes = { 
    # expires: 7.days.from_now.httpdate, 
    # cache_control: 'max-age=60480' 
    # } 

    config.cache_dir = "#{Rails.root}/tmp/uploads/" # To let CarrierWave work on heroku 

    # config.fog_directory = ENV['S3_BUCKET_NAME'] 
    #config.s3_access_policy = :public_read # Generate http:// urls. Defaults to :authenticated_read (https://) 
    #config.fog_host   = "#{ENV['S3_ASSET_URL']}/#{ENV['S3_BUCKET_NAME']}" 
end 

最後,報告模型本身

#app/models/report.rb 
class Report 
    include Neo4j::ActiveNode 
    searchkick word_start: [:name], autocomplete: [:name] 
    validates_presence_of :name 
    validates_uniqueness_of :name, case_sensitive: false 

    property :avatar, type: String 
    mount_uploader :avatar, AvatarUploader 

    def search_data 
    { 
     name: name, 
     description: description 
    } 
    end 

    property    :name 
    property    :description 
    property    :tableau_link 
    property    :type 
    property    :thumbnail_uri 
    property    :gridsize 
    property    :timestamp 
    property    :embedJSON 
    property    :created_at 
    property    :updated_at 
    property    :created_by 
    property    :updated_by 
    has_many :in,   :terms 
    has_one :in,   :office 

    def selectable_terms 
    @selectable_terms = [] 
    self.terms.each do |t| 
     @selectable_terms << { id: t.id, text: t.name } 
    end 
    @selectable_terms.to_json 
    end 

    def update_terms(param_terms) 
    param_terms ||= [] 
    term_instances = [] 
    param_terms.each do |t| 
     term_instances << Term.find_by(name: t) 
    end 
    term_instances 
    end 
    def aggro_extro 
    embedJSON.present? ? JSON.parse(embedJSON) : Hash.new 
    end 
end 

一個原因,我能想到的是,我們正在使用:name字段作爲我們的唯一標識符。也許carrierwave正在尋找UUID呢?

另一種可能性是carrierwave正在緩存關聯。

回答

1

我最終取消了Carrierwave並使用Paperclip。我們正在使用回形針的寶石如下,以獲得圖像上傳與neo4j.rb很好玩的任何人遇到麻煩。對於回形針連接器的寶石是neo4j.rb球隊的paperclip-fork

gem 'rails', '4.0.2' 

gem 'neo4j', '~> 4.1.1' 

gem 'neo4jrb-paperclip', github: 'subvertallchris/neo4jrb-paperclip', require: 'neo4jrb_paperclip' 
gem 'aws-sdk-v1' 

新的報告模型 -

class Report 
    include Neo4j::ActiveNode 
    include Neo4jrb::Paperclip 

    has_neo4jrb_attached_file :avatar, 
          storage: :s3, 
          s3_permissions: :private, 
          default_url: '/assets/images/reports-icon-white.svg', 
          s3_credentials: 
           Proc.new { |a| a.instance.s3_credentials } 
    validates_attachment_content_type :avatar, 
            content_type: ['image/jpg', 
                'image/jpeg', 
                'image/png', 
                'image/gif'] 
    # Rather than rename our variables in our secrets file, just rename them here 
    def s3_credentials 
    { 
     bucket: ENV['S3_BUCKET_NAME'], 
     access_key_id: ENV['S3_KEY'], 
     secret_access_key: ENV['S3_SECRET'] 
    } 
    end 
2

我剛試過,它似乎工作。我猜你正在使用舊版本的neo4j/neo4j-core寶石,不過因爲當我嘗試使用你的模型時,它指出你沒有指定type選項。從版本5.0.0開始,這是必需的。你可以更新到5.2.0系列,看看是否解決了這個問題?另外請注意,6.0.0將很快推出(發佈候選已經出來)。

我想提的是,你應該爲你的模型中的name屬性指定一個索引。這應該有助於在查詢名稱時。既然你正在做validates_uniqueness_of你甚至可能想指定一個約束。該約束不會確保這些值在大小寫不敏感的情況下是唯一的,但它會在數據庫級別對您進行一些唯一性約束。您仍然需要validates_uniqueness_ofcase_sensitive: false。請參閱下面的文檔:

http://neo4jrb.readthedocs.org/en/5.2.x/ActiveNode.html#indexes http://neo4jrb.readthedocs.org/en/5.2.x/ActiveNode.html#constraints

還要注意的是限制自動創建索引,所以你不需要同時指定(實際上在6.0.0我們不會讓你這樣做了) 。

+0

我們的應用程序確實使用'寶石 '的Neo4j',「〜> 4.1.1''。感謝Brian的快速回復!我們結束了與回形針,並取得了巨大的成功。 –