Search code examples
validationruby-on-rails-4limitcarrierwavenested-attributes

Rails 4 How to validate the number of nested attributes(multiple image/picture) using carrierwave


i'm new to stackoverflow & Rails. I have three models, User, Post, post_attachment(Create post_attachment scaffold). What i want to do is , every post(Title of post,Content,Picture) user can only upload 5 pictures maximum(i mean each post). I referred this article to achieve multiple image and basically followed this code. I also found this article to validate nested_attributes but only picture validation(nested_attributes) is not working. Any ideas would be appreciated. Thanks.

User.rb:

class User < ActiveRecord::Base
   has_many :posts, dependent: :destroy 
end

Post.rb:

class Post < ActiveRecord::Base
   belongs_to :user
   has_many :post_attachments
   accepts_nested_attributes_for :post_attachments,allow_destroy: true, reject_if: :all_blank
end

Post_attachment.rb:

class PostAttachment < ActiveRecord::Base
   mount_uploader :picture,PictureUploader 
   belongs_to :post
end

Post_controller.rb:

def new
   @post = Post.new
   @post_attachment = @post.post_attachments.build
end

def show
   @post_attachments = @post.post_attachments.all
end

def create
   @post = current_user.posts.build(post_params)

  if @post.save
    params[:post_attachments]['picture'].each do |a|
          @post_attachment = @post.post_attachments.create!(:picture => a, :post_id => @post.id)
    end
    redirect_to @post, notice: "Post Saved" 
   else
     render 'new'
  end
end

private

def post_params
   params.require(:post).permit(:title,:content,:user_id,post_attachments_attributes: [:id, :post_id, :picture, :_destroy])
end

Solution

  • You can put condition before create and edit methods and also in edit.html.erb. like if you want to save maximum 5 photos you can use

    def create
      @post = current_user.posts.build(post_params)
    
      if @post.save
        ##@post_attachments = PostAttachment.find_by_post_id(@post.id) --> this can be use in edit
        ##if params[:post_attachments]['picture'].length+ @post_attachment.length <= 5
         if params[:post_attachments]['picture'].length <= 5
           params[:post_attachments]['picture'].each do |a|
              @post_attachment = @post.post_attachments.create!(:picture => a, :post_id => @post.id)
           end
         elsif params[:post_attachments]['picture'].length > 5
           flash[:error] = 'Your message'
           redirect_to YOUR_PATH
           return false
         end
         redirect_to @post, notice: "Post Saved" 
      else
       if params[:post_attachments]['picture'].length > 5
          @post.errors[:base] << "Maximuim 5 messages/pictures."
       end
       render 'new'
     end
    end
    

    also you can check in view while editing your post.

    <% if @post_attachments.length <= 5 %>
       <%= f.file_field %>
    <% end %>