Ruby on Rails で画像をアップロード(paperclip, fog)

>>> サンプルアプリケーションはこちらです <<<

今日は Ruby on Rails で画像をアップロード出来るサイトの作り方をご紹介させて頂きます。

OPTIONAL: Bootstrapの開発環境を自動的に作る

まず、ImageMagick をインストールする必要がありますので、ImageMagick のないパソコンならインストールしてください。

Mac OS: brew install imagemagick
Ubuntu: sudo apt-get install imagemagick

では、始めましょう!

Gemfile
gem 'paperclip'
gem 'fog'

Article というScaffoldを作る:
rails g scaffold Article title content:text

それでpaperclip photo を作る:
rails g paperclip article photo

それとも実際にマイグレーションのファイルを追加してもいいです:

db/migrate/20141124111234_create_articles.rb
  def change
    create_table :articles do |t|
      t.string :title
      t.text :content

      t.timestamps
    end

    add_attachment :articles, :photo
  end

データベースをマイグレート: rake db:migrate

paperclip を設定

development環境

config/environments/development.rb
  config.paperclip_defaults = {
    :use_timestamp => false,
    :styles        => { large: '500x500>', medium: '300x300#', thumb: '120x120!' },
    :url           => '/:attachment/:class/:id/:basename_:style.:extension',
    :path          => ':rails_root/public:url',
    :default_url   => '/:attachment/errors/missing_:style.png',
    :default_style => :original
  }

今、:styles のところを見ると、三つの種類があります。

例えば、画像の元はこれとすると:
1.jpg

'数1x数2>' は画像の広さは数1で、高さは広さに対して変わります。
1a.jpg

'数1x数2#' は画像の広さは数1で、高さは数2になります、画像はクロップされます。
1b.jpg

'数1x数2!' は画像の人さは数1で、高さは数2になりますが、画像は圧搾されます。
1c.jpg

:default_url は画像がない時に、:default_url に書いてある画像が使われます。

production環境

AMAZON WEB SERVER (AWS) を利用します。

config/environments/production.rb
  config.paperclip_defaults = {
    :use_timestamp   => false,
    :styles          => { large: '500x500>', medium: '300x300#', thumb: '120x120!' },
    :path            => ':attachment/:class/:id/:basename_:style.:extension',
    :default_url     => '/:attachment/errors/missing_:style.png',
    :default_style   => :original,
    :storage         => :fog,
    :fog_directory   => ENV['FOG_DIRECTORY'],
    :fog_credentials => {
      :provider              => :aws,
      :region                => 'ap-northeast-1',
      :aws_access_key_id     => ENV['AWS_ACCESS_KEY_ID'],
      :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
    }
  }

aws-sdk を使う場合:

gem 'aws-sdk', '< 2.0'

    :storage        => :s3,
    :s3_credentials => {
      :s3_host_name       => 's3-ap-northeast-1.amazonaws.com',
      :bucket             => ENV['S3_DIRECTORY'],
      :access_key_id      => ENV['AWS_KEY'],
      :secret_access_key  => ENV['AWS_SECRET']
    }

大体development.rbと同じです、

:fog_directory はAWSのBucket名です。

:regionはBucketのregionによって違います。

region リスト

region名 コード
US East (N. Virginia) us-east-1
US West (Oregon) us-west-2
US West (N. California) us-west-1
EU (Ireland) eu-west-1
EU (Frankfurt) eu-central-1
Asia Pacific (Singapore) ap-southeast-1
Asia Pacific (Sydney) ap-southeast-2
Asia Pacific (Tokyo) ap-northeast-1
South America (Sao Paulo) sa-east-1
app/models/article.rb
  has_attached_file :photo
  validates_attachment :photo,
    content_type: { content_type: ["image/png", "image/jpeg", "image/jpg"] },
    size: { in: 0..12000.kilobytes }
app/controllers/articles_controller.rb
    def article_params
      params.require(:article).permit(:title, :content, :photo)
    end
app/views/articles/_form.html.slim
= form_for @article do |f|
  .field
    = f.label :photo
    = f.file_field :photo, accept: 'image/jpeg, image/jpg, image/png'

画像を表す:

  = image_tag @article.photo
  = image_tag @article.photo(:large)
  = image_tag @article.photo(:medium)
  = image_tag @article.photo(:thumb)

画像を消す:

@article.photo = nil
@article.save

画像が保存されるかどうかを確認:

@article.photo.file?
@article.photo?

jQuery Mobile を使う場合:

app/views/articles/_form.html.slim
= form_for @article, html: { multipart: true, 'data-ajax'=>false } do |f|
Created by Yuto at 2022-01-21 17:42
0
Like this article