HomebrewでImageMagickをインストールします。
ターミナルで以下のコマンドを実行してください。
brew install imagemagick
記述追加 GemFile(71行目)
gem 'paperclip', '~> 5.1.0'
GemFile
source 'https://rubygems.org' git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") "https://github.com/#{repo_name}.git" end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.0.7', '>= 5.0.7.1' # Use postgresql as the database for Active Record gem 'pg', '>= 0.18', '< 2.0' # Use Puma as the app server gem 'puma', '~> 3.0' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2' # See https://github.com/rails/execjs#readme for more supported runtimes # gem 'therubyracer', platforms: :ruby # Use jquery as the JavaScript library gem 'jquery-rails' # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.5' # Use Redis adapter to run Action Cable in production # gem 'redis', '~> 3.0' # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platform: :mri end group :development do # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. gem 'web-console', '>= 3.3.0' gem 'listen', '~> 3.0.5' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] # bootstrap gem 'bootstrap-sass', '~> 3.4.1' # デバイス gem 'devise', '~>4.2' # Gravatar gem 'gravtastic' #フラッシュメッセージ gem 'toastr-rails', '~> 1.0' #日本語化 gem 'rails-i18n' #画像アップロード gem 'paperclip', '~> 5.1.0'
コマンド
bundle
記述追加 config\environments\development.rb(3行目)
Paperclip.options[:command_path] = "/usr/local/bin/"
config\environments\development.rb
Rails.application.configure do #画像アップロード Paperclip.options[:command_path] = "/usr/local/bin/" # Settings specified here will take precedence over those in config/application.rb. # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false # Do not eager load code on boot. config.eager_load = false # Show full error reports. config.consider_all_requests_local = true # Enable/disable caching. By default caching is disabled. if Rails.root.join('tmp/caching-dev.txt').exist? config.action_controller.perform_caching = true config.cache_store = :memory_store config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=172800' } else config.action_controller.perform_caching = false config.cache_store = :null_store end # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = true config.action_mailer.perform_caching = false # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load # Debug mode disables concatenation and preprocessing of assets. # This option may cause significant delays in view rendering with a large # number of complex assets. config.assets.debug = true # Suppress logger output for asset requests. config.assets.quiet = true # Raises error for missing translations # config.action_view.raise_on_missing_translations = true # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. config.file_watcher = ActiveSupport::EventedFileUpdateChecker config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } #Gメールの設定 config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: "smtp.gmail.com", port: 587, enable_starttls_auto: true, authentication: "plain", user_name: 'win.rails.learn@gmail.com', password: 'vusopllqzbyvvahk' } end
「config\initializers」フォルダに「paperclip_media_type_spoof_detector_override.rb」ファイルを新規作成します。
config\initializers\paperclip_media_type_spoof_detector_override.rb(新規作成したファイル)
require 'paperclip/media_type_spoof_detector' module Paperclip class MediaTypeSpoofDetector def spoofed? false end end end
コマンド
写真モデルを作成します。
rails g model Photo room:references
コマンド
rails g paperclip photo image
更新
db\migrate\20200628021623_add_attachment_image_to_photos.rb
1行目に[5.0]の記述を追加して下さい。
class AddAttachmentImageToPhotos < ActiveRecord::Migration[5.0] def self.up change_table :photos do |t| t.attachment :image end end def self.down remove_attachment :photos, :image end end
コマンド マイグレーション適用
rails db:migrate
app\models\room.rb
「has_many :photos」の記述を追加します。(4行目)
class Room < ApplicationRecord belongs_to :user has_many :photos validates :home_type, presence: true validates :room_type, presence: true validates :accommodate, presence: true validates :bed_room, presence: true validates :bath_room, presence: true end
記述追加 app\models\photo.rb(5,6行目)
class Photo < ApplicationRecord belongs_to :room has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" } validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/ end
記述追加 config\routes.rb
「resources :photos, only: [:create, :destroy]」の記述を追加してます。(19行目)
resources :rooms, except: [:edit] do member do get 'listing' get 'pricing' get 'description' get 'photo_upload' get 'amenities' get 'location' end resources :photos, only: [:create, :destroy] end
config\routes.rb
Rails.application.routes.draw do #ルートをpages#homeに設定 root 'pages#home' get 'pages/home' resources :users, only: [:show] resources :rooms, except: [:edit] do member do get 'listing' get 'pricing' get 'description' get 'photo_upload' get 'amenities' get 'location' end resources :photos, only: [:create, :destroy] end devise_for :users, path: '', path_names: {sign_in: 'login', sign_out: 'logout', edit: 'profile', sign_up: 'registration'}, controllers: {registrations: 'registrations'} # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
「app\controllers」フォルダに「photos_controller.rb」ファイルを新規作成します。
app\controllers\photos_controller.rb
class PhotosController < ApplicationController def create @room = Room.find(params[:room_id]) if params[:images] params[:images].each do |img| @room.photos.create(image: img) end @photos = @room.photos redirect_back(fallback_location: request.referer, notice: "保存しました。") end end end
更新 app\controllers\rooms_controller.rb
「photo_update()」メソッドに「@photos = @room.photos」追加したり(37行目)、「before_action :is_authorised」に「:photo_upload」を追加(4行目)しています。
また、「is_authorised」メソッドの記述(65行目)により部屋登録者以外はアクセスできないようにしています。
内容をそのまま置き換えてください。
class RoomsController < ApplicationController before_action :set_room, except: [:index, :new, :create] before_action :authenticate_user!, except: [:show] before_action :is_authorised, only: [:listing, :pricing, :description, :photo_upload, :amenities, :location, :update] def index @rooms = current_user.rooms end def new @room = current_user.rooms.build end def create @room = current_user.rooms.build(room_params) if @room.save redirect_to listing_room_path(@room), notice: "保存しました。" else flash[:alert] = "問題が発生しました。" render :new end end def show end def listing end def pricing end def description end def photo_upload @photos = @room.photos end def amenities end def location end def update new_params = room_params new_params = room_params.merge(active: true) if is_ready_room if @room.update(new_params) flash[:notice] = "保存しました。" else flash[:alert] = "問題が発生しました。" end redirect_back(fallback_location: request.referer) end private def set_room @room = Room.find(params[:id]) end def is_authorised redirect_to root_path, alert: "権限がありません。" unless current_user.id == @room.user_id end def is_ready_room !@room.active && !@room.price.blank? && !@room.listing_name.blank? && !@room.photos.blank? && !@room.address.blank? end def room_params params.require(:room).permit(:home_type, :room_type, :accommodate, :bed_room, :bath_room, :listing_name, :summary, :address, :is_tv, :is_kitchen, :is_air, :is_heating, :is_internet, :price, :active) end end
更新 app\views\rooms\photo_upload.html.erb
ファイルを置き換えてください。
<div class="row"> <div class="col-md-3"> <%= render 'room_menu' %> </div> <div class="col-md-9"> <div class="panel panel-default"> <div class="panel-heading"> お写真 </div> <div class="panel-body"> <div class="container"> <div class="row"> <div class="col-md-offset-3 col-md-6"> <!-- PHOTOS UPLOAD GOES HERE --> <%= form_for @room, url: room_photos_path(@room), method: 'post', html: {multipart: true} do |f| %> <div class="row"> <div class="form-group"> <span class="btn btn-default btn-file text-babu"> <i class="fa fa-cloud-upload" aria-hidden="true"></i> 写真を選択 <%= file_field_tag "images[]", type: :file, multiple: true %> </span> </div> </div> <div class="text-center"> <%= f.submit "写真追加", class: "btn btn-normal" %> </div> <% end %> </div> </div> <div id="photos"><%= render 'photos/photos_list' %></div> </div> </div> </div> </div> </div>
「app\views」フォルダに「photos」フォルダを新規作成します。
作成した「photos」フォルダに「_photos_list.html.erb」ファイルを新規作成します。
app\views\photos\_photos_list.html.erb(新規作成したファイル)
<% if @photos.count > 0 %> <br/><br/> <div class="row"> <% @photos.each do |photo| %> <div class="col-md-4"> <div class="panel panel-default"> <div class="panel-heading preview"> <%= image_tag photo.image.url() %> </div> </div> </div> <% end %> </div> <% end %>
ブラウザ確認
登録したお部屋に写真をアップロードしてみます。
一度ターミナルを起動しなおして下さい。
http://localhost:3000/rooms/1/photo_upload