小编Dan*_*n L的帖子

使用Rails 3.2和AJAX(非Flash上​​传解决方案)将多个文件直接上传到Amazon S3

这个问题困扰了我好几个小时,我似乎无法找到解决方案.

我有一个rails 3.2应用程序,允许用户使用carrierwave_direct,fog和carrierwave(对carrierwave_direct的依赖)将文件上传到Amazon S3帐户.使用carrierwave_direct允许用户通过将文件直接发送到Amazon S3来跳过将文件上传到服务器(保存服务器处理和Heroku等大文件的超时).

如果您只是选择1个文件,将其上传到亚马逊,并希望重定向到您提供亚马逊的URL,它就可以正常工作.它通过将表单发布到Amazon S3来执行此操作,并且Amazon使用URL中的一些参数响应提供的URL(您在表单中指定此URL),然后将其存储为模型中Amazon上的文件的指针.

所以生命周期是:选择1个文件,POST到亚马逊,亚马逊用一个URL回复你的另一个页面,然后你可以保存一个带有指向亚马逊文件的指针的记录.

我一直想弄清楚的是如何选择和上传多个文件并更新上传进度?我正在尝试使用纯javascript(使用现代浏览器提供的文件API)这样做,所以我不想要任何第三方工具.另外,在深入学习这个问题的过程中,我正在避免使用任何插件,并且我正在尝试自己编写代码.

我想要获得的功能是:

  1. 用户看到带有文件字段的表单(或拖放)
  2. 用户选择多个文件(单击文件字段或拖放)
  3. 使用Javascript(还没有服务器),构建一个要上传的选定文件的队列(只使用浏览器文件API,只需文件名和大小)
  4. 然后,用户单击"开始上载"按钮
  5. 迭代队列中的每个文件并将文件POST到Amazon S3; 亚马逊将使用URL响应每个POST,并且该URL需要通过Javascript处理,而不是作为标准请求; 亚马逊提供的URL将创建一个记录,用于存储指向Amazon文件的指针; 创建记录后,代码将转到队列中的下一个文件,直到完成为止.

在这一点上,我甚至可以没有个人进度条; 我很乐意在没有页面刷新的情况下将多个文件发布到Amazon S3.

我并不偏爱任何宝石.我实际上害怕如果我真的希望以特定方式完成它,我将不得不从头开始写我想做的事情.目标是通过AJAX将多个文件上传到Amazon S3帐户.即使是如何处理问题的一般概念,我也会欣喜若狂.我花了很多时间在谷歌搜索这个,我还没有找到任何可以做我想要的解决方案.任何帮助都将非常感激.

编辑2014-03-02

Raj询问我是如何实现多重上传的.这已经很久了,我不记得我所做的所有"为什么"(可能是糟糕的代码,因为这是我第一次),但这就是我的目标.

我上传的模型是推荐书,其中相关图像存储在Amazon S3中.它允许用户选择多个图像(我认为它们实际上是我转换为图像的PDF文件)并将它们拖放到屏幕上.在上传时,我显示了一个模式,向用户提供有关需要多长时间的反馈.

我不会假装记住我在很多方面所做的事情,但如果它有助于随意使用它.

# Gemfile
# For client-side multiple uploads
gem "jquery-fileupload-rails"

# For file uploads and Amazon S3 storage
gem "rmagick"
gem "carrierwave"
gem "fog"
Run Code Online (Sandbox Code Playgroud)

这是观点:

# app/views/testimonials/new.html.erb
<div id="main" class="padded">
  <div class="center">
    <div id="dropzone">
      Click or Drop Files here to Upload
    </div>

    <%= form_for @testimonial do |f| %>
      <div class="field">
        <%= file_field_tag …
Run Code Online (Sandbox Code Playgroud)

jquery file-upload ruby-on-rails amazon-s3 ruby-on-rails-3

5
推荐指数
1
解决办法
7422
查看次数

Rails 4 Carrierwave + RMagick,将 PDF 转换为 PNG 会更改文件编码而不是扩展名?

我可以上传 PDF 并将其转换为 PNG 格式,并通过<%= image_tag "path/to/image" %>帮助程序在浏览器中正确呈现。但是,实际的文件扩展名并未从 PDF 更改为 PNG。因此,如果您下载图像,它会下载为 image.pdf。下载后,如果您手动将扩展名更改为“png”,它会在本地计算机上正确打开图像软件。我希望 RMagick 进程自动更改扩展名以及文件格式。我可以编写一些代码来删除 PDF 并在保存文件时添加 PNG 扩展名,但似乎我在这里遗漏了一些东西。我认为当我转换为不同的格式时,这应该自动完成。这是我的ImageUploader.rb课。我正在使用 Carrierwave 和 RMagick。

# app/uploads/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick
  include Sprockets::Rails::Helper

  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  process :convert_to_png

  def convert_to_png
    manipulate!(format: "png", read: { density: 400 }) do |img, index, options|
      options = { quality: 100 }
      img.resize_to_fill!(850, 1100)
      img
    end
  end

 # Add 'png' file extension so file becomes 'image.pdf.png'
 def filename
    "#{original_filename}.png" if …
Run Code Online (Sandbox Code Playgroud)

pdf ruby-on-rails rmagick carrierwave

5
推荐指数
1
解决办法
2986
查看次数

Rails 表单在数组上使用 collection_radio_buttons 而不是对象

Rails 有一个表单助手f.collection_radio_buttons,其操作与表单助手非常相似f.collection_select

但是,f.colleciton_radio_buttons仅适用于对象集合,不适用于简单数组。

作为一个例子,我可以有:

<%= f.select :attribute, ["First", "Second"] %>
Run Code Online (Sandbox Code Playgroud)

但没有:

<%= f.radio_buttons :attribute, ["First", "Second"] %>
Run Code Online (Sandbox Code Playgroud)

因此,要使用f.collection_radio_buttons一个简单的数组,我必须这样做:

<%= f.collection_radio _buttons :attribute, ["First", "Second"], :to_s, :to_s %>
Run Code Online (Sandbox Code Playgroud)

这“有效”,但看起来很老套。有没有一种更干净的方法来引用数组的值而不是调用.to_s它?

forms collections ruby-on-rails radio-button

5
推荐指数
1
解决办法
2560
查看次数

Rails 5.2+:为什么仍然在webpacker中使用资产管道?

我正在阅读Rails webpacker gem文档,其中说:

Webpacker使使用JavaScript预处理器和捆绑程序webpack 4.x.x +轻松管理Rails中类似应用程序的JavaScript。它与资产管道共存,因为webpack的主要用途是类似应用的JavaScript,而不是图像,CSS甚至JavaScript Sprinkles(所有这些都继续存在于应用/资产中)。

但是,也可以将Webpacker用于CSS,图像和字体资产,在这种情况下,您甚至不需要资产管道。仅在使用基于组件的JavaScript框架时,这才最重要。

我试图了解背后使用的基本原理对CSS /图像/ JS-洒旧资产管道如果webpacker能够处理这一切?

我读过其他一些文章,这些文章引导我逐步使用webpacker,但我不理解此决定的原因。

这是否只是为了支持旧版应用程序,最终旧的资产管道将消失,而webpacker将用于Rails应用程序中的所有内容?

javascript ruby-on-rails webpack

5
推荐指数
1
解决办法
357
查看次数

Rails 6+、zeitwerk 自动加载器和命名空间常量

Rails 6+ 的默认自动加载器是 zeitwerk,这似乎比以前的方法有了很大的改进。

但是,zeitwork 遵循 Rails 项目的约定,即其中的任何内容app/*都是自动加载的,不需要命名空间。

这非常app/models/user.rb有用,因为您不必使用Models::User但可以只引用User.

但是,我添加了自己的app/services目录,并将我的服务对象命名为Services::Users::Create,它将映射到app/services/users/create.rb.

Zeitwork 正在抛出我的类常量不存在的错误,因为它是预期的Users::Create(没有Services::前缀)。

无论如何要配置 zeitwork 以Services::在这些实例中要求命名空间?在我看来,阅读代码Services::Users::Create并知道您正在查看app/services/users/create.rb文件要干净得多。

如果只有Users::Create,一般的 Rails 开发人员可能会查找该app/models/users/create.rb文件。

我不喜欢命名它的方法Users::CreateService,它对我来说似乎很不雅。

我不能是唯一一个使用这样的约定的人;有没有其他人遇到过解决方案?我仍在浏览所有 zeitwerk 文档以寻找解决方案,但还没有找到。

autoload ruby-on-rails-6 zeitwerk

4
推荐指数
1
解决办法
1521
查看次数

Rails 4:浏览器关闭时会话值永远不会“过期”或死亡

请参阅问题末尾的更新

在 Rails 4 中,我知道会话默认情况下只存在于浏览会话中。如果您关闭了浏览器,会话将不再存在。

但是,我认为情况并非如此。我有一个使用 Rails 提供的所有默认值的 Rails 4 应用程序。我正在处理一些身份验证代码并遇到了这个问题。

当用户登录系统时,他们可以通过复选框选择“记住我”。当他们选中此框时,会话的有效期应为 2 周。目标是当用户登录系统并关闭浏览器时,他可以再次打开浏览器并使用该应用程序,而无需再次进行身份验证。

另一方面,如果用户不想选中“记住我”框并登录应用程序并关闭浏览器,当浏览器再次打开时,用户应该被要求再次进行身份验证,因为他的会话“过期”时浏览器关闭。

问题是我的会话永远不会消失。我测试了一些简单的代码,其中在第 1 页上我在控制器中设置了一个会话变量,然后在第 2 页上显示了该会话。当我关闭浏览器并转到第 2 页(不是第 1 页,因此不会再次设置会话)时,会话仍然像以前一样存在。

我认为会话应该在浏览器默认关闭时过期?我也用“cookies”而不是会话尝试过这个,并得到了相同的结果。

简而言之,当用户关闭浏览器时,我怎样才能获得过期/死亡的会话/cookie?如果用户不希望他们保留所有会话,对我来说似乎不是很安全,而且我不会让我的用户每次关闭浏览器时删除他们的 cookie(可能在公共计算机上他们的登录信息应该只保留到他们关闭浏览器)。

更新 我想我找到了可能导致问题的原因。我使用 Chrome 作为我的浏览器,当浏览器关闭和打开时,我将它设置为“记住我离开的地方”。这似乎保存了所有会话/cookie。我也用 Gmail 验证了这一点。如果您设置了“记住我离开的地方”,但没有在 Gmail 中设置记住我的令牌,当您关闭/打开浏览器时,Gmail 会立即打开。如果您告诉 Chrome 在打开时打开一个新标签页,那么 Gmail 会像我预期的那样将您发送到登录页面。

这样就解决了一个问题,但整体问题仍然存在。我怎样才能使这个“安全”?假设您在公共计算机上,当浏览器打开时,恶意用户将浏览器设置为“记住我离开的地方”。因此,您登录了一个应用程序(例如 Gmail),但不要选中“记住我”框。因此,当您关闭浏览器时,您希望您的登录是“安全的”。但是如果另一个用户打开浏览器备份,他已经登录到你的应用程序。

这是我可以切实防止的事情吗?如果 Gmail 有这个缺陷(拥有一群非常聪明的开发人员),我是否应该担心这种情况存在?

security authentication session-cookies ruby-on-rails-4

3
推荐指数
1
解决办法
2983
查看次数

Rails 4 验证消息:从消息中删除“_id”

# model.rb
validates :employee_id, presence: true, uniqueness: true
Run Code Online (Sandbox Code Playgroud)

留空时,错误消息显示“员工不能为空”,而我希望它说“员工 ID 不能为空”。

我通过以下方式解决了这个问题:

# model.rb
validates :employee_id, presence: { message: " ID can't be blank" }, uniqueness: true
Run Code Online (Sandbox Code Playgroud)

输出“员工 ID 不能为空”。

然而,这不是一个很好的解决方案 IMO。我想要一些自定义整个消息的方法,包括属性前缀。

有没有一种简单的方法可以做到这一点?

validation ruby-on-rails-4 rails-activerecord

3
推荐指数
1
解决办法
2356
查看次数

缩进终端/shell 输出

我已经广泛定制了终端提示符的外观/感觉,以便它输出以下内容(用于开发工作):

== [~/current/path] (git_branch_name) $

==当我查看大型文本博客时,我使用来帮助识别提示行。

然而,使用几个月后,我发现很难轻松浏览终端并知道是什么。

我的想法是缩进所有输出会有所帮助。我知道我也可以改变颜色,但想同时使用这两种解决方案。

但我不知道如何缩进发送到终端的所有输出。MAN 页面对我没有帮助,我在 Google 上也找不到太多信息。

我正在尝试做什么

$ some_command_that_outputs_text All lines of output are indented 2 spaces... All lines of output are indented 2 spaces... All lines of output are indented 2 spaces... All lines of output are indented 2 spaces... $ another_terminal_prompt More lines are indented 2 spaces... More lines are indented 2 spaces... More lines are indented 2 spaces... More lines are indented 2 spaces...

更新时间:2014-10-24

请注意,我已经为我的终端以及提示本身自定义了配色方案。我发现配色方案不足以让我个人找到我的命令,因为大部分文本本身的颜色与我的提示本身相似。

shell terminal command-prompt

3
推荐指数
1
解决办法
5661
查看次数

RSpec和FactoryGirl - 建立独特的关联?

一个feedback模型需要account存在.每个account都有一个唯一的:在模型中验证的uuid:validates :uuid, presence: true, uniqueness: true

我使用rspec来测试反馈模型,并且Uuid has already been taken每当我构建一个feedback对象时都会出现错误,因为反馈正在构建一个关联的account

规格/型号/ feedback_spec.rb

require "spec_helper"

describe Feedback do
  it "is valid with a message" do
    expect(build(:feedback)).to be_valid
  end

  it "is invalid without a message" do
    expect(build(:feedback, message: nil)).to have(1).errors_on(:message)
  end

  it "is invalid without an associated account" do
    expect(build(:feedback, account: nil)).to have(1).errors_on(:account)
  end
end
Run Code Online (Sandbox Code Playgroud)

规格/工厂/ feedbacks.rb

FactoryGirl.define do
  factory :feedback do
    association :account
    message Faker::Lorem.paragraphs
  end
end
Run Code Online (Sandbox Code Playgroud)

规格/工厂/ …

testing rspec-rails ruby-on-rails-4 factory-bot

2
推荐指数
1
解决办法
1761
查看次数

Rails:在同一张桌子上运行的多个模型

我正在构建一个系统,该系统在表中包含一些记录,这些记录是模板记录,所有帐户都可以查看这些记录,并且可以在以后复制以创建单个帐户的实时记录。

这个设计决定背后的原因是模板记录和实时记录共享 95% 以上的相同代码,所以我不想创建一个单独的表来跟踪大部分相同的字段。

例如,我有一张workflows桌子:

  • id:整数
  • account_id:整数
  • 名称:字符串(必填)
  • is_a_template:boolean(默认值:false)
  • is_in_template_library:boolean (默认: false)

在这个表中,我有一些作为模板的记录。当我去创建一个新的实时记录时,我可以使用模板记录:

# workflows_controller.rb (pseudo-code, not fully tested)
def create
  @workflow_template = Workflow.where(is_a_template: true).find_by(id: params[:workflow_template_id])
  @workflow = current_account.workflows.new(workflow_params.merge(@workflow_template.dup))

  if @workflow.save
    ...
  else
    ...
  end
end
Run Code Online (Sandbox Code Playgroud)

随着我构建更多功能,我发现我真的需要 2 种不同的模型,它们在桌子上的操作方式各不相同。还有更多不同之处,但下面列出的那些足以显示差异:

class Workflow < ApplicationRecord
  default_scope -> { where(is_a_template: false) }

  belongs_to :account

  validates :account, presence: true
  validates :name, presence: true
end

class WorkflowTemplate < ApplicationRecord
  default_scope -> { where(is_a_template: true) }

  validates :name, presence: true
end

class WorkflowLibraryTemplate < …
Run Code Online (Sandbox Code Playgroud)

templates ruby-on-rails

2
推荐指数
1
解决办法
2528
查看次数

Rails 4:before_save回调无法正常工作

我有一个lookups带有子ContractType模型的多态表.我before_saveContractType模型中有一个回调设置category,但它似乎没有工作.

class Lookup < ActiveRecord::Base
  validates :value, presence: true
  validates :category, presence: true
end

class ContractType < Lookup
  before_save { self.category = "contract_type" }
end
Run Code Online (Sandbox Code Playgroud)

然后我打开rails c:

> c = ContractType.create(value: "test")
> c.errors.messages
=> { :category => ["can't be blank"] }
Run Code Online (Sandbox Code Playgroud)

我没有得到任何错误,只是验证失败.据我所知,语法看起来是正确的,只是before_save回调似乎不起作用......

我错过了一些明显的东西吗?

polymorphism activerecord callback ruby-on-rails-4

0
推荐指数
1
解决办法
2427
查看次数