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.
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