1

I can upload a file with using carrierwave as shown in the following code. How can I edit the code to make it possible to upload images up to 3 files in one article?

views\articles\new.html.erb

.
.
<div class="span8">
    <%= render 'shared/article_form' %>
</div>
.
.

views\shared\ _article_form.html.erb

.
.
<%= form_for(@article) do |f| %>
  <div class="field">
  <%= f.hidden_field :category_id %>
  <%= f.fields_for :photos do |p| %>
    <%= p.hidden_field :article_id %>
    <% if p.object.image and p.object.image.file %>
      <%= image_tag p.object.image.thumb.url %>
      <p><%= p.object.image.file.filename %></p>
    <% end %>
    <%= p.file_field :image %>
  <% end %>
  <%= f.text_area :content, placeholder: "Enter contents..." %>
  </div>
  <%= f.submit class: "btn btn-large btn-primary" %>
<% end %>
.
.

\models\article.rb

class Article < ActiveRecord::Base
  belongs_to :user
  belongs_to :category
  has_many :photos, dependent: :destroy
  accepts_nested_attributes_for :photos
  .
  .
end

\models\photo.rb

class Photo < ActiveRecord::Base
  belongs_to :article
  mount_uploader :image, ImageUploader
  validates :image, presence: true
end

\controllers\articles_controller.rb

class ArticlesController < ApplicationController
  .
  .
def new
  @article = Article.new
  @category = Category.find(params[:category])
  @article.category_id = @category.id
  @article.photos.build
end

def create
  @article = current_user.articles.build(article_params)
  if @article.save
    flash[:success] = "article created!"
    redirect_to current_user #root_url
  else
    @feed_items = []
    render 'new'
  end
end

def edit
  @article = Article.find(params[:id])
end

def update
  @article = Article.find(params[:id])
  if @article.update(article_params)
    redirect_to current_user
  else
    render 'edit'
  end
end
  .
  .
private

  def article_params
    params.require(:article).permit(:content, :category_id, photos_attributes: [:id, :article_id, :image])
  end
  .
  .
end
1
  • use "nested_form" or "cocoon" gem. that will make your job much simpler. Commented Aug 10, 2014 at 6:01

2 Answers 2

1

Change your new action to this:

def new
  @article = Article.new
  @category = Category.find(params[:category])
  @article.category_id = @category.id
  @photo = @article.photos.build
end

and in your file_field you need to use multiple option so your form will look like this:

<%= form_for(@article,:html => { :multipart => true }) do |f| %>
  // article fields
  <%= f.fields_for @photo do |p| %>
    <%= p.file_field :image, multiple: true %>
  <% end %>
<% end %>

Update

Change your new action and build a photo 3 times

def new
  @article = Article.new
  @category = Category.find(params[:category])
  @article.category_id = @category.id
  3.times { @article.photos.build } 
end

and your form

<%= form_for(@article,:html => { :multipart => true }) do |f| %>
  // article fields
  <%= f.fields_for :photos do |p| %>
    <%= p.file_field :image %>
  <% end %>
<% end %>

Also you'll have to modify your model a bit too in order to reject blank values

class Article < ActiveRecord::Base
  belongs_to :user
  belongs_to :category
  has_many :photos, dependent: :destroy
  accepts_nested_attributes_for :photos, reject_if: proc { |attributes| attributes[:image].blank? }
  .
  .
end
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your comment Mandeep, but I don't want to use multiple: true. I'd like to display <%= p.file_field :image %> 3 times in _article_form.html.erb and submit these images.
thank you for your prompt reply. I could upload 3 files, but I'd like to upload one file at least. In your updated code, 3 files are necessary because of validates :image, presence: true. How can I check one file is mandatory?
@SamuraiBlue add the reject block in your model and also make a custom validation where you'll check if there's at least one image present
0

You just have to add :html => { :multipart => true } to your form to upload multiple files.

<%= form_for(@article,:html => { :multipart => true }) do |f| %>

And also you have to change this line <%= p.file_field :image %> to <%= p.file_field :image, :multiple => true %>

1 Comment

Thank you for your comment Pavan, but I don't want to use multiple => true. I'd like to display <%= p.file_field :image %> 3 times in _article_form.html.erb and submit these images.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.