Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4: How do I handle a submitted form where nothing was selected?

Sorry if the title is a little confusing. I have a form for an Item with the field name. There's a text field where the user can input a name and submit it. But if the user doesn't type in anything and hits submit, Rails gives me a param not found: item error, and I'm not sure who to get around this.

items_controller.rb

def new
  @item = Item.new()

  respond_to do |format|
    format.html
    format.json { render json: @item }
  end
end

def create
  @item = Item.new(item_params)

  respond_to do |format|
    if @item.save
      format.html { redirect_to items_path }
      format.json { render json: @item, status: :created, location: @item }
    else
      format.html { render action: 'new', :notice => "Input a name." }
      format.json { render json: @item.errors, status: :unprocessable_entity }
    end
  end
end

private

def item_params
  params.require(:item).permit(:name)
end

app/views/items/new.html.haml

= form_for @item do |f|
  = f.label :name
  = f.text_field :name
  = f.submit "Submit"

The params.require(:item) part is what is causing the error. What the convention for handling the error when params[:item] isn't present?

like image 301
justindao Avatar asked Jul 19 '13 16:07

justindao


2 Answers

It's late for an answer but i'll still write it for someone else. As stated in rails guides you need to use fetch instead of require in strong parameters, by using fetch you can provide a default value if nothing is passed as input. Something like:

params.fetch(:resource, {}) 
like image 149
Mandeep Avatar answered Oct 01 '22 22:10

Mandeep


Update:

Scaffolded rails4 app: https://github.com/szines/item_17751377

It works if a user keep name field empty when create a new item...

Looks, it works without problem...

Development.log shows that parameters would be the following if user keep a field empty:

"item"=>{"name"=>""}

There is always something in the hash...

As Mike Li already mentioned in a comment, something wrong... because shouldn't be empty this params[:item]...

You can check if something nil, with .nil? , in this case params[:item].nil? will be true if it is nil. Or you can use .present? as sytycs already wrote.

Previous answer:

If you have situation when :item is empty, you should just use params[:item] without require.

def item_params
  params[:item].permit(:name)
end

More information about require in strong_parameters.rb source code:

# Ensures that a parameter is present. If it's present, returns
# the parameter at the given +key+, otherwise raises an
# <tt>ActionController::ParameterMissing</tt> error.
#
#   ActionController::Parameters.new(person: { name: 'Francesco' }).require(:person)
#   # => {"name"=>"Francesco"}
#
#   ActionController::Parameters.new(person: nil).require(:person)
#   # => ActionController::ParameterMissing: param not found: person
#
#   ActionController::Parameters.new(person: {}).require(:person)
#   # => ActionController::ParameterMissing: param not found: person
def require(key)
  self[key].presence || raise(ParameterMissing.new(key))
end
like image 25
Zoltan Avatar answered Oct 01 '22 23:10

Zoltan