質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

1回答

5254閲覧

carrierwaveでローカルに画像を保存できない

lyzmfeqpxs54

総合スコア237

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2017/11/16 10:06

編集2022/01/12 10:55

いつもお世話になります。

railsで文字と画像を投稿し表示できるようなページを作成しております。以下のよう書いているのですが下記エラーが出てしまいます。

undefined method `convert' for #ImageUploader:0x99d6d70 Did you mean? concern

投稿者名(poster_name)、投稿内容(post_text)、イメージ用のパス(attachment_name)の3つ(全てstring形式)をActiveRecordに保存したいのですがattachment_nameに文字列を保存しようとしても保存されない状況です。

画像をアップロードする記事は多くあるのですが、データベースに一度保存しそれを表示するという内容はなかなか見かけずこちらに質問させて頂きました。

間違っている箇所などをご指摘いただければと思います。
よろしくお願いいたします。

Ruby

1postしているパラメータ 2{"utf8"=>"✓", "authenticity_token"=>"llXh以下略==", "poster_name"=>"", "post_text"=>"", "attachment_name"=>#<ActionDispatch::Http::UploadedFile:0x4dbd910 @tempfile=#<Tempfile: 3C:/Users/ユーザー名/AppData/Local/Temp/RackMultipart20171113-6468-19agl2u.png>, @original_filename="detailMain_chihuahua.png", @content_typ 4 5e="image/png", @headers="Content-Disposition: form-data; name=\"attachment_name\"; filename=\"detailMain_chihuahua.png\"\r\nContent-T 6ype: image/png\r\n">, "commit"=>"送信", "id"=>"xxxxx"} 7 8 9 10コントローラー側 11def update 12 newrecord = モデル名.new 13 newrecord.poster_name = params[:poster_name] 14 newrecord.post_text = params[:post_text] 15  ### ↓でエラー 16  ### ここをnewrecord.attachment_name = "適当な文字列" 17  ### としてもレコードにはnilしか保存されない 18 newrecord.attachment_name = params[:attachment_name] 19 20 newrecord.save 21 if newrecord.save 22 redirect_to controller: 'home', action: 'show' 23 else 24 render "post/post" 25 end 26 end 27 28view側 29#投稿画面 30<%= form_with(model: @userinfo, local: true, html: {id: 'inform_save', class: 'form', autocomplete: 'off'}) do |f| %> 31 <div class="field"> 32 <%= f.label :poster_name, "投稿者名" %> 33 <%= f.text_field :poster_name, size: 25, value: "", id: "poster_name", class: "poster_name" %> 34 </div> 35 <div class="field"> 36 <%= f.label :post_text, "投稿内容" %> 37 <%= f.text_field :post_text, size: 25, value: "", id: "post_text", class: "post_text" %> 38 </div> 39 <div class="field"> 40 <%= f.file_field :attachment_name, class: 'attachment_name' %> 41 </div> 42 <div class="actions"> 43 <%= f.submit '送信' %> 44 </div> 45<% end %> 46 47モデル側 48 49#モデル名.rb 50class モデル名 < ApplicationRecord 51 mount_uploader :attachment_name, ImageUploader 52end 53 54#image_uploader.rb 55class ImageUploader < CarrierWave::Uploader::Base 56 57 # Include RMagick or MiniMagick support: 58 # include CarrierWave::RMagick 59 # include CarrierWave::MiniMagick 60 61 # Choose what kind of storage to use for this uploader: 62 storage :file 63 # storage :fog 64 process convert: 'jpg' 65 # Override the directory where uploaded files will be stored. 66 # This is a sensible default for uploaders that are meant to be mounted: 67 def store_dir 68 "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 69 end 70 71 # Provide a default URL as a default if there hasn't been a file uploaded: 72 # def default_url(*args) 73 # # For Rails 3.1+ asset pipeline compatibility: 74 # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) 75 # 76 # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 77 # end 78 79 # Process files as they are uploaded: 80 # process scale: [200, 300] 81 # 82 # def scale(width, height) 83 # # do something 84 # end 85 86 # Create different versions of your uploaded files: 87 # version :thumb do 88 # process resize_to_fit: [50, 50] 89 # end 90 91 # Add a white list of extensions which are allowed to be uploaded. 92 # For images you might use something like this: 93 def extension_whitelist 94 %w(jpg jpeg gif png) 95 end 96 97 # Override the filename of the uploaded files: 98 # Avoid using model.id or version_name here, see uploader/store.rb for details. 99 def filename 100 "something.jpg" if original_filename 101 end 102 103end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

carrierwave で convert メソッドを使用するためには、画像処理用のライブラリである
RMagick の gem をインストールする必要があります。
以下のエラーが出るのはこの RMagick ライブラリがインストールされていないのが原因です。

undefined method `convert' for #<ImageUploader:0x99d6d70> Did you mean? concern

もし jpg に変換する必要がないなら、この convert の行は削除してください。
その場合は、RMagick をインストールする必要はありません。
もし変換する必要があるなら Gemfile に以下の行を追加してください。

# Gemfile gem 'rmagick'

Gemfile の追記後に以下を実行し gem をインストールしてください。

$ bundle install

このときマシンに ImageMagick がインストールされていない場合はエラーが出ますが、
「rmagick インストール できない」などのワードで調べれば、解決できると思います。
無事インストールが済んだら、Rails のアプリケーションを再起動する必要があります。

次に image_uploreder.rb に include CarrierWave::RMagick を追加してください。

ruby

1# image_uploader.rb 2class ImageUploader < CarrierWave::Uploader::Base 3 include CarrierWave::RMagick 4 5 # 以下略... 6end

これで carrierwave で RMagick が使用できるようになります。
Controller 側ですが、 newrecord = モデル名.new としてしまうと
常に新しいレコードが作成されてしまいます。もし更新する場合は、
以下のように find を使うようにしてください。

Ruby

1# Controller 側 2 def update 3 @model = Model.find(params[:id]) 4 @model.poster_name = params[:poster_name] 5 @model.post_text = params[:post_text] 6 @model.attachment_name = params[:attachment_name] 7 8 if @model.save 9 redirect_to controller: 'home', action: 'show' 10 else 11 render "post/post" 12 end 13end

@modelModel と書いている部分は適宜置き換えてください。

掲示されているコードでは、save が2回呼ばれているので、レコードが2回保存されてしまいます。
if の前の save は必要ないので、削除してください。

また、もし View 側で画像を表示する場合は以下のコードを追加してみてください。

<!-- View 側 --> <%= image_tag(@model.attachment_name.url) if @model.attachment_name? %>

@model と書いている部分は適宜置き換えてください。

ちなみに image_uploader.rb 内で以下のコードが書かれているとすべてのファイルが
something.jpg としてなってしまいます。

def filename "something.jpg" if original_filename end

もしオリジナルのファイル名を使いたいなら、この部分はコメントアウトしてください。
拡張子だけ .jpg に変換したい場合は、以下のようにすると良いと思います。

def filename super.chomp(File.extname(super)) + '.jpg' if original_filename.present? end

carrierwave における Rmagick の使い方については以下を参考にしました。
https://github.com/carrierwaveuploader/carrierwave#using-rmagick

投稿2017/11/20 12:03

gesorein

総合スコア101

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問