Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4 enum validation

This is the first time I'm using enums with rails 4 and I ran into some issues, have couple of dirty solutions in mind and wanted to check are there any more elegant solutions in place :

This is my table migration relevant part:

create_table :shippings do |t|
  t.column :status, :integer, default: 0
end

My model:

class Shipping < ActiveRecord::Base
  enum status: { initial_status: 0, frozen: 1, processed: 2 }
end

And I have this bit in my view (using simple form for) :

= f.input :status, :as => :select, :collection => Shipping.statuses, :required => true, :prompt => 'Please select', label: false

So in my controller:

  def create
    @shipping = Shipping.create!(shipping_params)

    if @shipping.new_record?
      return render 'new'
    end

    flash[:success] = 'Shipping saved successfully'
    redirect_to home_path
  end

private

  def shipping_params
    params.require(:shipping).permit(... :status)
  end

So when I submit create form and the create action fire I get this validation error :

'1' is not a valid status

So I thought I knew that the issue was data type so I added this bit in the model :

before_validation :set_status_type

  def set_status_type
    self.status = status.to_i
  end

But this didn't seem to do anything, how do I resolve this ? Has anyone had the similar experience?

like image 398
Gandalf StormCrow Avatar asked Aug 31 '14 22:08

Gandalf StormCrow


1 Answers

You can find the solution here.

Basically, you need to pass the string ('initial_status', 'frozen' or 'processed'), not the integer. In other words, your form needs to look like this:

<select ...><option value="frozen">frozen</option>...</select>

You can achieve this by doing statuses.keys in your form. Also (I believe) you don't need the before_validation.

Optionally, you could add a validation like this:

validates_inclusion_of :status, in: Shipping.statuses.keys

However, I'm not sure that this validation makes sense, since trying to assign an invalid value to status raises an ArgumentError (see this).

like image 122
Albert Vila Calvo Avatar answered Sep 22 '22 04:09

Albert Vila Calvo