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

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

ただいまの
回答率

90.84%

  • Ruby

    6769questions

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

  • Ruby on Rails 4

    2372questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

  • Ruby on Rails 5

    1105questions

Ruby on RailsのCarrierWaveについて

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 175

ruby_egg

score 6

Ruby on Railsを独学で勉強しております、初心者です。
今、簡単なブログサイトを勉強で開発しております。

以下のサイトを参考にしながらCarrierWaveで複数の画像を投稿する仕組みを開発しております。
https://qiita.com/sinagaki58/items/a0d59cc41c6824bb5f67
https://qiita.com/_Yasuun_/items/a7e4a2e44c3c27ec3ba2
https://qiita.com/Tommy1218/items/6349d8d860c5982771ff

コードは以下の通りです。

Post.rb(投稿)
# == Schema Information
#
# Table name: posts
#
#  id         :integer          not null, primary key
#  user_id    :integer          not null
#  title      :string           not null
#  content    :text
#  status     :string           default("draft"), not null
#  created_at :datetime         not null
#  updated_at :datetime         not null
#  deleted_at :datetime
#
# Indexes
#
#  index_posts_on_deleted_at  (deleted_at)
#  index_posts_on_user_id     (user_id)
#

class Post < ApplicationRecord
  has_many :photos, class_name: "PostPhoto", dependent: :destroy
  accepts_nested_attributes_for :photos
end
PostPhoto.rb(投稿の写真)
# == Schema Information
#
# Table name: post_photos
#
#  id         :integer          not null, primary key
#  post_id    :integer          not null
#  image      :string           
#  created_at :datetime         not null
#  updated_at :datetime         not null
#
# Indexes
#
#  index_post_photos_on_post_id  (post_id)
#

class PostPhoto < ApplicationRecord

  belongs_to :post

  validates :image,
    presence: true

  mount_uploader :image, PictureUploader
end
post_controller.rb

def new
    @post = Post.new
    3.times { @post.photos.build }
  end

  # 投稿の編集フォーム
  def edit
    @post = current_user.posts.find(params[:id])
    @post.photos.each do |photo|
      photo.image.cache!
    end
  end

  def create
    @post = current_user.posts.new(post_params)
    if @post.save
      redirect_to @post, notice: "投稿しました"
    else
      render :new
    end
  end

  def update
    @post = current_user.posts.find(params[:id])
    if @post.update_attributes(post_params)
      redirect_to @post, notice: "投稿を編集しました。"
    else
      render :edit
    end
  end

  private
    def post_params
      params.require(:post).permit(:title, :content, :status, photos_attributes: [:image])
    end
Posts/new.html.slim, edit.html.slim

= form_for(@post, html: { multipart: true }) do |form|
  = form.fields_for :photos do |photo|
    = photo.file_field :image
      = form.hidden_field :image_cache
   = form.submit "上記の内容で作成する"

上記のコードですと、複数の画像3つをアップロード出来ますが、更新するときに、画像が削除されずに追加されます。
(3枚から6枚などになります)

さらに、更新の画面やバリデーションのエラーの際、前回、新規作成の時に写真を3枚アップロード済みですが、以下のように「選択されていません」と表示されます。(DBには保存されているが、image_cacheが正確に動いていないため?)
![イメージ説明](b7aeca4c8ff2c17d659b2f600f045d05.png)

【質問したい内容】
①更新の時は、「選択されていません」ではなく、前回アップロードしたファイルのファイル名を表示させる
②複数の画像3つを更新するときに、画像が削除されずに追加される仕様から、3つの内、更新した画像のみを新しくアップロードする
③Post(投稿)のphoto(写真)は最大で3枚にする(1〜2枚でも可)

アドバイスなどよろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

自分で以下のように実装いたしました。

post_controller.rb

  def new
    @post = Post.new
    3.times { @post.photos.build }
  end

  # 投稿の編集フォーム
  def edit
    @post = current_user.posts.find(params[:id])

    if @post.photos.count == 1
      2.times { @post.photos.build }
    elsif @post.photos.count == 2
      1.times { @post.photos.build }
    elsif @post.photos.count == 0
      3.times { @post.photos.build }
    end
  end

  # 投稿の新規作成
  def create
    @post = current_user.posts.new(post_params)
    if @post.save
      redirect_to @post, notice: "投稿しました"
    else
      3.times { @post.photos.build }
      render 'new'
    end
  end

  # 投稿の更新
  def update
    @post = current_user.posts.find(params[:id])
    if @post.update_attributes(post_params)
      redirect_to @post, notice: "投稿を編集しました。"
    else
      if @post.photos.count == 1
        2.times { @post.photos.build }
      elsif @post.photos.count == 2
        1.times { @post.photos.build }
      elsif @post.photos.count == 0
        3.times { @post.photos.build }
      end
      render :edit
    end
  end

  private

  def post_params
      params.require(:post).permit(:title, :content, :status, photos_attributes: [:id, :image, :_destroy])
    end

上記のように実装すると、②と③の内容は解決しました。
が、①の内容はまだ分かりません。
さらに、新規作成や更新の画面で写真をアップロードした状態でバリデーションエラー画面になると写真のフォームが4つとかに増えてしまします。(3つまでにしたいです)

アドバイスなど、よろしくお願いいたします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/10 17:54

    何故か解決いたしました。。。

    キャンセル

0

自分で色々と調べてみましたところ①は出来ないという事が分かりました。
そこで以下のようにコードを修正致しました。

post_controller.rb

# 投稿の新規登録フォーム
  def new
    @post = Post.new
    3.times { @post.photos.build }
  end

  # 投稿の編集フォーム
  def edit
    @post = current_user.posts.find(params[:id])

    if @post.photos.count == 1
      2.times { @post.photos.build }
    elsif @post.photos.count == 2
      1.times { @post.photos.build }
    elsif @post.photos.count == 0
      3.times { @post.photos.build }
    end
  end

  # 投稿の新規作成
  def create
    @post = current_user.posts.new(post_params)
    if @post.save
      redirect_to @post, notice: "投稿しました"
    else
      render 'new'
    end
  end

  # 投稿の更新
  def update
    @post = current_user.posts.find(params[:id])
    if @post.update_attributes(post_params)
      redirect_to @post, notice: "投稿を編集しました。"
    else
      render :edit
    end
  end

  private
  def post_params
    params.require(:post).permit(:title, :content, :status, photos_attributes: [:id, :image, :_destroy])
  end
Posts/new.html.slim, edit.html.slim
= form_for(@post, html: { multipart: true }) do |form|
  = form.fields_for :photos do |photo|
    = photo.file_field :image
    br
    - if @post.persisted?
      = photo.check_box :_destroy
      = photo.label :_destroy, "写真を削除"
  = form.submit "上記の内容で編集する"

上記のように修正すると、全体的には上手くいくのですが
createアクションのバリデーションエラーの画面で、写真のフォームが消えてしまします。
そこで以下のように修正すると、バリデーションエラーになった回数分、写真のフォームの数が増えてしまします。

post_controller.rb 

# 投稿の新規作成
  def create
    @post = current_user.posts.new(post_params)
    if @post.save
      redirect_to @post, notice: "投稿しました"
    else
      @post.photos.build
      render 'new'
    end
  end

バリデーションエラーになった場合でも写真のフォームを常に3つ表示させるにはどのようにすればよろしいでしょうか?

アドバイスなど、よろしくお願いいたします!

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Ruby

    6769questions

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

  • Ruby on Rails 4

    2372questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

  • Ruby on Rails 5

    1105questions