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

### [>>> サンプルアプリケーションはこちらです <<<](https://renshu-upload-image.herokuapp.com/)

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

#### OPTIONAL: [Bootstrapの開発環境を自動的に作る](http://qiita.com/YutoYasunaga/items/f53e62d850570eb85e4f)

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

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

では、始めましょう！

```ruby:Gemfile
gem 'paperclip'
gem 'fog'
```

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

**それでpaperclip photo を作る：**
`rails g paperclip article photo`

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

```ruby: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環境

```ruby: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](https://qiita-image-store.s3.amazonaws.com/0/35605/4a3c556d-e662-fac9-c5fd-dcccc66c74a2.jpeg)

'数1x数2>' は画像の広さは数1で、高さは広さに対して変わります。
![1a.jpg](https://qiita-image-store.s3.amazonaws.com/0/35605/8e53e53d-a310-d456-1cba-1cdca3dd6ef1.jpeg)

'数1x数2#' は画像の広さは数1で、高さは数2になります、画像はクロップされます。
![1b.jpg](https://qiita-image-store.s3.amazonaws.com/0/35605/51935f2c-c7a6-8417-135e-11c4da2a5366.jpeg)

'数1x数2!' は画像の人さは数1で、高さは数2になりますが、画像は圧搾されます。
![1c.jpg](https://qiita-image-store.s3.amazonaws.com/0/35605/ad563a0a-52b9-bb31-43bc-e9d27941381a.jpeg)

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


#### production環境

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

```ruby: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 を使う場合：**

```rb
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



```ruby: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 }
```

```ruby:app/controllers/articles_controller.rb
    def article_params
      params.require(:article).permit(:title, :content, :photo)
    end
```

```ruby: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'
```

**画像を表す：**

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

**画像を消す：**

```ruby 
@article.photo = nil
@article.save
```

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

```ruby 
@article.photo.file?
@article.photo?
```

#### jQuery Mobile を使う場合：

```ruby:app/views/articles/_form.html.slim
= form_for @article, html: { multipart: true, 'data-ajax'=>false } do |f|
```