使用neo4j的Rails 4应用程序和使用neo4j.rb gem的carrierwave-neo4j将图像附加到Report对象。
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 upload而不是:file可以正常上传,但同样缺少关联。
这是我的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
载波初始化器
#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?
另一种可能性是载波正在缓存关联。
答案 0 :(得分:2)
我只是尝试过它似乎有效。我猜测你正在使用neo4j
/ neo4j-core
宝石的旧版本,因为当我尝试使用你的模型时,它指出你还没有指定一个type
选项。从版本5.0.0
开始,这是必需的。您是否可以更新到5.2.0
系列,看看是否能解决问题?另请注意,6.0.0
很快就会推出(候选版本已经发布)。
我要提到的其他一些事情是您应该为模型中的name
属性指定索引。这应该有助于查询名称。由于您正在执行validates_uniqueness_of
,您甚至可能希望指定约束。约束不会以不区分大小写的方式确保值是唯一的,但它会在数据库级别为您做一些唯一性约束。您仍然希望validates_uniqueness_of
加case_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中我们不允许您再这样做)。
答案 1 :(得分: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