• 如何attach一个或多个文件到一个记录.has_many_attach()方法。
  • 如何删除一个附加的文件。 purge方法
  • 如何连接到一个附加的文件。url_for()
  • 如何使用variants来转化image。 ⚠️Variant/Variation模块
  • 如何generate一个文件代表无图像的文件,如PDF,或者video。⚠️忽略了。
  • 如何从浏览器发送一个文件上传到一个存储服务storage service, 通过你的应用服务 direct_upload: true方法,另外还增加了JavaScript event⚠️
  • 在测试期间如何clear储存的文件⚠️我用的是参考书上的方法。
  • 如何implement 支持 为额外的储存服务。⚠️还需要看帖子。

教程视频:

step by step 的网页,包括还未掌握的云存储,和服务器相关步骤:

https://afreshcup.com/home/2017/07/23/activestorage-samples 


1.什么是ActiveStorage?

Active Storage上传文件到一个云存储服务如AmazonS3. 并且附加这件文件到Active Record objects。它基于本地磁盘服务,可以用于开发和测试以及支持镜像文件给次级服务用于备份和迁移。

使用Active Storage,一个程序可以转化文件通过ImageMagick上传。 以及生成文件代表无图像的文件,如PDF,或者video,以及提取元数据从任意文件。


2. Setup

ActiveStorage使用2个数据表储存文件。

运行rails active_storage:install  生成这2个数据表。

如果在本地开发,在config/environments/development.rb中,

config.active_storage.service = :local  #默认已经设置了。

声明Active Storage 服务 在config/storage.yml中。 为了让你的程序使用云服务,需要提供一个名字和必须的配置。如amazon的配置:

本地和测试是默认的。

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>
local:
  service: Disk
  root: <%= Rails.root.join("storage") %>
amazon:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
  region: us-east-1
  bucket: your_own_bucket

你需要告诉Active Storage使用那个server。设定:

Rails.application.config.active_storage.service

因为每个环境使用的服务不一样。所以推荐提前在环境中设置好。比如要在开发环境使用前面案例的disk 服务 , 你需要在config/environments/development.rb设置:

config.active_storage.service = :local     #默认已经设置了。

如果在production中,使用AmazonS3服务,配置config/environments/production.rb:

config.active_storage.service = :amazon

当然还要读更多的信息关于内置服务适配器adapters(如Disk和S3)和它们需要的配置。

2.1Disk Service

声明 disk服务,在config/storage.yml中,默认已有了。

2.2 Amazon S3 Service

同样需要在config/storage.yml中设置。

另外需要下载他的gem:gem 'aws-sdk-s3', require: false

(主流的云服务都有gem)具体的都需要看相关文档。

其他Microsoft, Google(都需要下载gem)

2.5 Mirror Service

通过定义一个镜像服务,你可以持有多个云服务在异步下。

当一个文件上传或删除,它就通过了所以的镜像服务。

在产品环境中,镜像服务之间能够通过一个迁移来使用。

你开业开始镜像一个新的服务,拷贝现存的文件从旧服务到新服务,然后把所有的放在新服务上

Define each of the services you'd like to use as described above and reference them from a mirrored service.(不懂⚠️)

s3_west_coast:
  service: S3
  access_key_id: ""
  secret_access_key: ""
  region: ""
  bucket: ""
 
s3_east_coast:
  service: S3
  access_key_id: ""
  secret_access_key: ""
  region: ""
  bucket: ""
 
production:
  service: Mirror
  primary: s3_east_coast
  mirrors:
    - s3_west_coast

文件们从主服务被服务。


3 Attaching Files to Records

3.1 has_one_attached

可以参考https://www.cnblogs.com/chentianwei/p/9169049.html的写法:

在创建一个对象时,不添加关联。之后再使用:

@user.avatar.attach(params[:user][:avatar]) 来附加一个文件。

或者也可以通过参数限制方法user_params直接创建:

def create
  user = User.create!(user_params)
  session[:user_id] = user.id
  redirect_to root_path
end
private
  def user_params
    params.require(:user).permit(:email_address, :password, :avatar)
  end

调用avatar.attached?可以确定对象是否有了一个文件,返回true/false

3.2 has_many_attached macro宏命令

一对多的关系。一条记录可以附加多个文件。假如有一个message有多个images:

has_many_attached :images, dependent:false  #记录删除但附加文件不会删除。

class MessagesController < ApplicationController
  def create
    message = Message.create!(message_params)
    redirect_to message
  end
 
  private
    def message_params
      params.require(:message).permit(:title, :content, images: [])
    end
end

⚠️,如果使用has_many, 注意传的是一个数组,

更新:(7-1)

在views/_form.html.slim中,用form_for:

  div.form-group
    = f.label :images
    = f.file_field :images, multiple: true, class:"form-control"

就会在web, products/new中显示一个上传框:choose files,⚠️是files, 这样就可以上传多个文件了。✌️

全代码:

h2 后台,产品目录
ul
  - @products.each do |product|
    li = link_to product.title, admin_product_path(product)
    - if product.avatar.attached?
        li = link_to image_tag(url_for(product.avatar), size: "100"), rails_blob_path(product.avatar, disposition:"attachment")
    - if product.images.attached?
      - product.images.each do |image|
        - if image.variable?
            li = link_to image_tag(image.variant(resize: "400x400")), rails_blob_path(image, disposition:"attachment")
            p = image.filename
        - elsif image.previewable?
            li = image_tag image.preview(resize: "200x200")
        - else
            li = image.filename

备注:product.avatar.variable? =>true; product.avatar.image? =>true;

图片既是image也是variable.

更新 7-2

假设@post有一个image

file_field(:image, accept: 'image/png,image/gif,image/jpeg')

:accept - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.

问题:如何设置validations。验证上传文件的格式。自定义?

使用“how to validate uploaded file type in rails 5.2”进行google search

  1. 得到2018年的搜索记录。看第一条。
  2. 看相关的网页:
https://stackoverflow.com/questions/48158770/activestorage-file-attachment-validation

https://github.com/rails/rails/issues/31656 (还没有看。)

在product.rb中

validate :must_type

  def must_type
    if avatar.attached?
      if avatar.blob.byte_size > 10
        errors[:base] << "#{avatar.blob.filename.to_s}太大,请选择小于10mb的文件。"

avatar.purge

      elsif !avatar.blob.content_type.match(/^image\//)

# 使用in?(%w(image/png image/jepg))也可以。

        errors[:base] << '非法文件格式,只支持图片格式。'

avatar.purge

      end
    end

#if images.attached?  后面的代码大同小异,多images一个循环。

  end

在views/../_form.html.slim中添加file_field的时候,需要添加accept特性

= f.file_field :avatar, class:"form-control", accept: "image/jpg, image/jpeg, image/png, image/gif"


4 Removing Files

purge: 把文件从storage中清除。

可以从数据库直接删除:

ActiveStorage::Blob.find(

ActiveStorage Overview --Rails guide (history:7-1更新)的更多相关文章

  1. 转:Oculus Unity Development Guide开发指南(2015-7-21更新)

    http://forum.exceedu.com/forum/forum.php?mod=viewthread&tid=34175 Oculus Unity Development Guide ...

  2. An overview of gradient descent optimization algorithms (更新到Adam)

    Momentum:解快了收敛速度,同时也减弱了SGD的波动 NAG: 减速了Momentum更新参数太快 Adagrad: 出现频率较低参数采用较大的更新,对于出现频率较高的参数采用较小的,不共用一个 ...

  3. Rails Guide -- Ruby on Rake(未详细阅读)

    一个软件task管理和build 自动化的工具. 它允许用户指定tasks和describe dependencies, 也可以在一个namespace中group tasks. 使用Ruby语言写的 ...

  4. 基于TI Davinci架构的多核/双核开发高速扫盲(以OMAP L138为例),dm8168多核开发參考以及达芬奇系列资料user guide整理

    基于TI Davinci架构的双核嵌入式应用处理器OMAPL138开发入门 原文转自http://blog.csdn.net/wangpengqi/article/details/8115614 感谢 ...

  5. Ionic 2 Guide

    Ionic 2 Guide 最近一直没更新博客,业余时间都在翻译Ionic2的文档.之前本来是想写一个入门,后来觉得干脆把官方文档翻译一下算了,因为官方文档就是最好的入门教程.后来越翻译越觉得这个事情 ...

  6. Google C++ Style Guide在C++11普及后的变化

    转 http://www.cnblogs.com/chen3feng/p/5972967.html?from=timeline&isappinstalled=0&lwfrom=user ...

  7. iOS热更新技术被苹果官方警告?涉及到RN、Weex、JSPatch

    本文为转载文章 故事背景: 这两天,不少iOS开发群都炸窝了,原因是部分iOS开发者收到了苹果的警告邮件: 有开发者质疑可能是项目中使用了JSPatch.weex以及ReactNative等热更新技术 ...

  8. rails手脚架(scaffold)功能

    scaffold是一个高速开发rails应用的代码框架.能够使用一条命令实现CRUD操作. 1: 创建一个应用 rails new scaffoldapp cd scaffoldapp rails s ...

  9. Rails 最佳实践

    在你业务简单的时候,让你简简单单用 ActiveRecord 模型. 复杂的时候,你可以用官方推荐的 Concerns. 更复杂的时候,可以通过 gem 和 API 来拆分. 极端复杂的时候,由于 R ...

随机推荐

  1. postgresql----表分区

    --下面的描述不记得在哪里抄来的了?! 表分区就是把逻辑上一个大表分割成物理上的多个小块,表分区可提供如下若干好处: 1.某些类型的查询性能可以得到极大提升. 2.更新的性能可以得到提升,因为表的每块 ...

  2. 使用C#和HtmlAgilityPack解析HTML

    近期,有一个需求,需要解析HTML页面,读取一些需要的数据后,插入本地数据库.我知道可以通过正则表达式实现,然而正则表达式之于我,就像汇编语言之于我,一样.我知道它是干什么的,我也知道它能干什么,但是 ...

  3. Oracle HA 之 RAC one node实战

    --创建rac one node步骤 安装grid软件,配置grid集群:安装oracle软件:dbca创建rac one node. >试验创建的rac one node数据库信息如下: gl ...

  4. Modulo operation

    Modulo operation - Wikipedia https://en.wikipedia.org/wiki/Modulo_operation https://baike.baidu.com/ ...

  5. explain 分析 聚合统计语句的性能

    EXPLAIN SELECT COUNT(1) FROM question; id select_type table partitions type possible_keys key key_le ...

  6. Redis主从切换

    案例 易车网:http://www.greatops.net/?id=232 redis主从切换:http://www.cnblogs.com/itdragon/p/7932178.htmlhttps ...

  7. 【css a标签 鼠标悬浮时变手型】

    <a href="#" style="cursor:pointer">

  8. java爬取网页内容 简单例子(2)——附jsoup的select用法详解

    [背景] 在上一篇博文java爬取网页内容 简单例子(1)——使用正则表达式 里面,介绍了如何使用正则表达式去解析网页的内容,虽然该正则表达式比较通用,但繁琐,代码量多,现实中想要想出一条简单的正则表 ...

  9. 记一次mysql启动不了的问题

    在linux上用的是xampp,mysql启动没有报任何错误,但就是查找不到进程,于是找mysql错误日志,日志在哪?在lampp/var/mysql 以.err结尾的文件里.里面内容如下; /opt ...

  10. GIT学习笔记(1):创建版本库

    GIT学习笔记(1):创建版本库 创建版本库 1.创建合适目录并初始化为仓库 版本库即需要交由Git进行版本控制的目录,其下所有文件的修改.删除,Git都能跟踪还原. 说明:初始化后,当前目录下会多出 ...