Question

I've currently five boolean attributes. I do a custom validation on them :

def limit_impacts
    i = 0
    choices = [self.first_attr, self.sec_attr, self.third_attr, self.fourth_attr, self.fifth_attr]
    choices.each do |choice|
      if choice == true
        i+=1
      end
    end
    if i > 2
      errors[:base] << ("There must be one or two impacts.")
    end
  end

The idea is to test if more than two of them are set to true, if it's the case, set an error. I'm setting a :base error because it's not related directly to only one attribute.

I'm simply doing this for my validation : validate :limit_impacts

and the part of the view handling this :

  = f.input :first_attr, :as => :boolean

  = f.input :sec_attr, :as => :boolean

  = f.input :third_attr, :as => :boolean

  = f.input :fouth_attr, :as => :boolean

  = f.input :fifth_attr, :as => :boolean

The problem is, when I check more than 2 checkboxes the entrie is not saving and that's normal, but no error message is showing up in the view.

What am I doing wrong ?

By the way I tested it in rails console :

MyModel.errors[:base]
 => ["There must be one or two impacts."]

And this syntax doesn't work either :

errors.add :base, "message"

EDIT : Here's my controller. It's about the edit method.

  def edit
    @page_title = t('projects.edit.title')
    @project = Project.find(params[:id])
    @steps = @project.steps
    @rewards = @project.rewards
    @project_bearer = @project.user
  end

Nothing linked with these attributes.

When I try to create a project via the rails console, it returns me false :

2.0.0p247 :001 > t = Project.create(:social_influence => true, :environmental_influence => true, :economical_influence => true)
=> <Project all my attributes ..>
2.0.0p247 :002 > t.save
(1.2ms)  BEGIN
(2.0ms)  ROLLBACK
=> false 

SOLUTION :

The problem was my update method, bewteen render and redirect. Thanks to @delba I solved it. If you want to see the solution, there's a discussion in the comments of his answer.

Was it helpful?

Solution

In the view containing the form, make sure you display the errors:

<%= form_for @my_model do |f|
  <% if @my_model.errors.any? %>
    <ul class="errors">
      <% @my_model.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  <% end %>

  <%# the rest of the form %>
<% end %>

In your controller:

def create
  @my_model = MyModel.new(my_model_params)
  if @my_model.save
    redirect_to 'blabla'
  else
    render :new
  end
end

In your model:

validate :limit_impacts

private

def limit_impacts
  if [first_attr, sec_attr, third_attr, fourth_attr, fifth_attr].count(true) > 2
    errors[:base] << "There must be one or two impacts."
  end
end

OTHER TIPS

Let's start with your validation method:

def limit_impacts
  choices = [first_attr, sec_attr, third_attr, fourth_attr, fifth_attr]
  errors[:base] << "There must be one or two impacts." if choices.count(true) > 2
end

Much cleaner, isn't it? :)

Could you show us your layout / your view bit which displays errors? I will update answer then.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top