0

I have a model Person which can have many Cars and i want to create a nested form to create two records of car at once for which i am using accepts_nested_attributes_for. Allow to create two car records at once:

  1. Hatchback
  2. Sedan

A person with can leave the one or both of the car fields to be blank and i am using allow_blank to handle that.

Models:

#### Model: Car
class Car < ActiveRecord::Base
  belongs_to :person

  validates :registration_number, uniqueness: true, allow_blank: true,
              format: {with: SOME_REGEX}

  validate :both_cars_registration_cant_be_same

  def both_cars_registration_cant_be_same
    car1 = registration_number if type == 'hatchback'
    car2 = registration_number if type == 'sedan'
    if car1 == car2
      errors.add(:registration_number, "Both number can't be same")
    end
  end 

### Model : Person   
class Person < ActiveRecord::Base
  has_many :cars
  accepts_nested_attributes_for :cars, allow_destroy: true, 
           reject_if:  proc { |attr| attr['registration_number'].blank?  }

Controller:

### Controller : Person

class PersonsController < ApplicationController

  def new
    @person = Person.new
    2.times { @person.cars.build }
  end

Below is the small snippet of form partial

...
...
### _form.html.erb ###
<%= f.fields_for :cars do |car|
   <%= render 'car_form', c: car %>
<% end %>
...
...

### _car_form.html.erb  ###
<% if c.index == 0 %>
  <p>Type: Sedan</p>
  <%= c.hidden_field :type, value: "sedan" %>
<% else %>
  <p>Type: Hatchback</p>
  <%= c.hidden_field :type, value: "hatchback" %>
<% end %>

<div>
  <%= c.label :registration_number %>
  <%= c.text_field :registration_number %>
</div>

I can use validate :both_cars_registration_cant_be_same with valid? from Cars model in rails console but how do i run this validation from the parent model (person) so that i get the error message when the form is submitted with same registration number for two cars?. I want to validate that the registration number fields entered for two record must be different and not same. Also let me know if my form helper where i am using index on the fields_for object is the correct way to do it?

P.S : Using rails 4

bluefoggy
  • 961
  • 1
  • 9
  • 23
  • Remember `type` can only have one value per model instance in your validation. If `type` is neither `hatchback` nor `sedan` then the equality condition will be `nil == nil` which is `true`. In fact, it only appears to evaluate false if `type` is either `"hatchback"` or `"sedan"` AND `registration_number` is NOT `nil`. Perhaps this is what you want, but probably not, and either way there's some really confusing logic at play. I'd consider refactoring the validation logic to make it more clear. – Anthony E May 04 '16 at 19:59
  • yes i know i can fall into that trap, I will definately fix that but first i wanted to validate that both the registration number when entered (not nil) should be unique (not same). I wan't to catch that error first. – bluefoggy May 04 '16 at 20:31

2 Answers2

0

Move cars validation to Person model. This question could be helpful for you: Validate that an object has one or more associated objects

Community
  • 1
  • 1
dodo121
  • 114
  • 1
  • 5
  • I want to validate that the registration number fields entered for two record must be different and not same while create. If no fields are entered i will not validate. I am not sure how the above solution handles it? – bluefoggy May 04 '16 at 18:30
0

here is an example

belongs_to :project


validates_uniqueness_of :title, allow_blank: false, conditions: -> {where(parent_id: nil)}, scope: :project

use the scope validation option http://guides.rubyonrails.org/active_record_validations.html

Kirka121
  • 505
  • 4
  • 13
  • can you explain a bit about the "conditions:"? – bluefoggy May 04 '16 at 20:45
  • condition will run this validation only on collection members that meet the condition. so in this case, this is a folder, that has parent folders. so the condition is to validate uniqueness of folder titles with no parents, scoped under the project. so i can't have project1 with folder1 folder1, but i can have projcet1 with folder1 and project2 with folder1 - reference: http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html – Kirka121 May 05 '16 at 11:29
  • I don't get any error message in this. Does it really work ? – bluefoggy May 06 '16 at 17:37
  • Does it work for new records? . I don't know if the conditions of nil parent_id works. ? – bluefoggy May 06 '16 at 17:59