Search code examples
ruby-on-railsruby-on-rails-4carrierwavedelayed-job

Validation not working - param is missing or the value is empty carrierwave


I have search for my problem but I can't found any solution.

My model home with attributes such as : title, logo, description, keywords.

I'm using carrierwave + delayed job for upload a logo, the upload is works (create & update) but when file / input file is empty I got this error :

ActionController::ParameterMissing in SettingsController#home_update_b
param is missing or the value is empty: home

Extracted source (around line #99): 

  def home_update_b_params
      params.require(:home).permit(:logo)
  end
end

SettingsController

def index
 ## get one record without params
 @home = Home.take 
end

def home_update_b
  @home = Home.find(params[:id])
   if @home.update(home_update_b_params)
     respond_to do |format|
      format.html { redirect_to setting_home_path, :notice => "Logo successfully updated" }
      format.json { head :no_content }
      end 
   else
     respond_to do |format|
      format.html { 
           flash[:alert] = "There's Something Wrong"
           render :action => :home
      }
      format.json { render json: @home.errors, status: :unprocessable_entity }
     end
   end
end

private

def home_update_b_params
 params.require(:home).permit(:logo)
end

I'm sure on home model have validate

class Home < ActiveRecord::Base
    mount_uploader :logo, LogoUploader
    after_save :enqueue

    validates_presence_of :logo
end

form

<%= form_for(@home, :url => logo_update_path(@home), :html => { :class => "form-horizontal", :role => "form", :method => :put}) do |f| %>
  <div class="form-group">
    <%= f.label :logo, "Logo", :class => 'col-sm-3 control-label no-padding-right ace-file-input' %>
    <div class="col-sm-4">
            <%= f.file_field :logo, "data-file-input" => "easy" %>
    </div>
  </div>
  <div class="clearfix form-actions">
    <div class="col-md-offset-3 col-md-9">
      <%= f.submit %>
    </div>
  </div>
<% end %>

stack trace

Processing by SettingsController#home_update_b as HTML
  Parameters: {"utf8"=>"V", "authenticity_token"=>"gmXtbe31vfSPqM1N5taM1ge92nRvr
SpY91Y8vAlEBmc=", "commit"=>"Update Home", "id"=>"2"}
  ←[1m←[36mHome Load (0.0ms)←[0m  ←[1mSELECT  "homes".* FROM "homes"  WHERE "hom
es"."id" = $1 LIMIT 1←[0m  [["id", 2]]
Completed 400 Bad Request in 4ms

ActionController::ParameterMissing (param is missing or the value is empty: home
):
  app/controllers/settings_controller.rb:99:in `home_update_b_params'
  app/controllers/settings_controller.rb:60:in `home_update_b'

When I add another attribute to form (e.g title), input file still empty and it's works to update, but validation not works for input file is empty.

FYI Rails 4.1.1 and Ruby 1.9.3


Solution

  • If you are accepting any type of file from the user using an input type of "file" and the user doesn't select it, you won't get a key for that field in the parameter hash.

    In your case, you are accepting only a logo from the user, and if it's empty, the home key doesn't exist in your parameter hash, thus the require() method throws an exception because it didn't find the specified key.

    Instead of require() you can use the fetch() method which can return an empty hash as default value if the specified key is not found. Like this:

    params.fetch(:home, {}).permit(:logo)