Rails 5:远程表单失败

asc*_*man 1 ruby-on-rails heroku amazon-s3 carrierwave ruby-on-rails-5

我有一个用于在我的 rails 应用程序中创建产品的表单:

= form_for product, url: url, method: :post, html: { class: 'product-form' }, remote: true do |f|

  .row
    .col-xs-12.col-sm-6
      .form-group.required
        = f.label :name
        = f.text_field :name, autofocus: true, class: 'form-control'
    .col-xs-12.col-sm-6
      .form-group.required
        = f.label :price
        .input-group
          .input-group-addon $
          = f.number_field :price, class: 'form-control'

  .row
    .col-xs-12
      .form-group
        = f.label :description
        = f.text_area :description, class: 'form-control'

  .row
    .col-xs-12
      .form-group
        = label_tag :images, 'Images'
        = f.file_field :images, multiple: true, class: 'form-control'

  .row
    .col-xs-12.text-right
      = f.submit "Cancel", class: 'btn btn-default', data: { dismiss: "modal" }
      = f.submit "Save",  class: 'btn btn-primary'
Run Code Online (Sandbox Code Playgroud)

它在我的开发环境中运行良好。但是在 heroku(生产)上运行时,单击“保存”时失败(请注意,我正在使用 Devise 并且登录/注册工作正常),并出现以下错误:

2016-10-14T11:55:02.825234+00:00 app[web.1]: W, [2016-10-14T11:55:02.825168 #3] 警告——无法验证 CSRF 令牌的真实性。

2016-10-14T11:55:02.825602+00:00 app[web.1]: I, [2016-10-14T11:55:02.825555 #3] INFO -- : 在 1ms 内完成 422 个不可处理的实体 (ActiveRecord: )

2016-10-14T11:55:02.826511+00:00 app[web.1]: F, [2016-10-14T11:55:02.826471 #3] 致命 -- : ActionController::InvalidAuthenticityToken (ActionController)::InvalidAuthenticityToken

问题是当我不选择图像时,它工作正常。所以我认为问题可能出在图像上传器上

模型/产品.rb

class Product
  mount_uploaders :images, ProductImageUploader
  # more stuff...
end
Run Code Online (Sandbox Code Playgroud)

上传者/product_image_uploader.rb

class ProductImageUploader < CarrierWave::Uploader::Base
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
end
Run Code Online (Sandbox Code Playgroud)

初始值设定项/carrier_wave.rb

if Rails.env.development? || Rails.env.test?
  CarrierWave.configure do |config|
    config.storage = :file
    config.enable_processing = false if Rails.env.test?
  end
else
  CarrierWave.configure do |config|
    config.fog_provider = 'fog/aws'                        # required
    config.fog_credentials = {
      provider:              'AWS',
      aws_access_key_id:     ENV["AWS_KEY_ID"],
      aws_secret_access_key: ENV["AWS_KEY_SECRET"],
      region:                'us-west-2',                  # optional, defaults to 'us-east-1'
    }

    config.fog_directory = ENV['AWS_BUCKET']
    config.fog_public = true

    config.cache_dir = "#{Rails.root}/tmp/uploads"
  end
end
Run Code Online (Sandbox Code Playgroud)

另一件事是我尝试在生产中使用简单的 storage::file,避免 S3 上传内容,但它也失败了。

任何的想法?

更新!

我在表单中添加了authenticity_token: true并且它不会引发我上面提到的异常。然而,奇怪的事情正在发生:

  • 当我不从表单中选择图像时,POST 是远程完成的:

由 ProductsController#create as JS 处理

  • 当我在表单中选择一个图像时,POST 不是远程完成的:

由 ProductsController#create 处理为 HTML

更新 2!

这是为表单标签生成的 html:

<form class="product-form" id="new_product" enctype="multipart/form-data" action="/seller/products" accept-charset="UTF-8" data-remote="true" method="post">
  <input name="utf8" type="hidden" value="?">
  <input type="hidden" name="authenticity_token" value="SOME STUFF">     </form>
Run Code Online (Sandbox Code Playgroud)

Saj*_*jan 5

在表单声明中,remote: true添加authenticity_token: true如下内容后:

form_for product, url: url, method: :post, html: { class: 'product-form' }, remote: true, authenticity_token: true do |f|
Run Code Online (Sandbox Code Playgroud)