5

I'm trying to connect my Spree shopping cart with AWS S3 for product image uploads but I keep getting the error:

.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.2.0/lib/active_record/dynamic_matchers.rb:22:in `m
ethod_missing': undefined method `has_one_attached'

Here is my set-up:

Gemfile

ruby '2.4.0'
gem 'rails', '~> 5.2.0'
gem 'spree', '~> 3.6.0'
gem 'spree_auth_devise', '~> 3.3'
gem 'spree_gateway', '~> 3.3'
gem 'globalize', github: 'globalize/globalize'
gem 'spree_i18n', github: 'spree-contrib/spree_i18n'
gem 'spree_globalize', github: 'spree-contrib/spree_globalize', branch: 'master'
gem 'spree_static_content', github: 'spree-contrib/spree_static_content'
gem 'aws-sdk', '~> 2.3'

config/initializers/spree.rb

attachment_config = {

    s3_credentials: {
      access_key_id:     ENV['AWS_ACCESS_KEY_ID'],
      secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
      bucket:            ENV['S3_BUCKET_NAME']
    },

    storage:        :s3,
    s3_region:      ENV['S3_REGION'],
    s3_headers:     { "Cache-Control" => "max-age=31557600" },
    s3_protocol:    "https",
    bucket:         ENV['S3_BUCKET_NAME'],
    url:            ":s3_domain_url",

    styles: {
        mini:     "48x48>",
        small:    "100x100>",
        product:  "240x240>",
        large:    "600x600>"
    },

    path:           "/:class/:id/:style/:basename.:extension",
    default_url:    "/:class/:id/:style/:basename.:extension",
    default_style:  "product"
  }

  attachment_config.each do |key, value|
    Spree::Image.attachment_definitions[:attachment][key.to_sym] = value
  end

Has anyone come across this error and has a solution?

3 Answers3

2

For anyone having this problem in the future, this is how I've fixed it.

If you are editing the Spree::User class as an initializer, the problem is that the initializer from 'active_storage/reflection' did not run. So add these lines at the beggining of your class_eval block:

include ActiveStorage::Reflection::ActiveRecordExtensions

ActiveRecord::Reflection.singleton_class.prepend(ActiveStorage::Reflection::ReflectionExtension)

include ActiveStorage::Attached::Model

Afterwards, ActiveStorage should be loaded and you will be able to find the method has_one_attached :image

0

Comment lines attachment_config in spree.rb

Declare Active Storage services in config/storage.yml. For each service your application uses, provide a name and the requisite configuration.

amazon:
  service: S3
  access_key_id: ""
  secret_access_key: ""
  bucket: ""
  region: "" # e.g. 'us-east-1'

To use the Amazon S3 service in production, you add the following to config/environments/production.rb:

config.active_storage.service = :amazon

Add the aws-sdk-s3 gem to your Gemfile:

gem "aws-sdk-s3", require: false

Source: http://edgeguides.rubyonrails.org/active_storage_overview.html#setup

-1

That config doesn't work for me as well. Actually the steps are pretty straightforward. Declare the amazon configurations in storage.yml, add the aws gem and you are ready to go. ActiveStorage documentations has it all. http://edgeguides.rubyonrails.org/active_storage_overview.html#setup

zawhtut
  • 8,335
  • 5
  • 52
  • 76