2015-11-19 1 views
2

Приложение Rails 4 с neo4j и neo4j.rb gem с использованием carrierwave-neo4j для присоединения изображений к объекту Report.Carrierwave с Neo4j не сохраняет ассоциацию изображений с 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 вместо: файл отлично подходит для загрузки, но имеет такую ​​же отсутствующую ассоциацию.

Вот мой класс класса класса.

#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 

Причина я могу думать о том, что мы используем: имя поля, как наш уникальные идентификаторы. Может быть, carrierwave ищет UUID вместо этого?

Другая возможность заключается в том, что несущая волна кэширует ассоциацию.

ответ

1

Я закончил тем, что сломал Carrierwave и пошел с Paperclip. Драгоценные камни, которые мы используем с paperclip, выглядят следующим образом, для тех, у кого еще есть проблемы с загрузкой изображений для игры с 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' 

Новый доклад neo4j.rb команды model-

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_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 мы не позволяют этого делать) ,

+0

Наше приложение действительно с помощью 'Gem 'Neo4j',«~> 4.1.1''. Спасибо за быстрый ответ Брайан! Мы закончили тем, что поехали с скрепкой и с большим успехом. –