0

I have the following on my model:

validates_uniqueness_of :woeid

before_create :handle_woeid_issue

def handle_woeid_issue
    Rails.logger.info 'DID ENTER HERE'  #never enters here for some reason
    self.woeid = self.temp_woeid
  end

def self.create_if_not_existing(woeid)
    unless Location.find_by_woeid(woeid)
      Rails.logger.info '>>>> ' + Location.find_by_woeid(woeid).inspect #THIS OUTPUTS NIL
      gp = Place.find_by_woeid(woeid)
      Location.from_place(gp)
    end
  end

def self.from_place(gp)
    raise "Invalid argument " if geoplanet_place.nil?
    attrs = gp.attributes.dup
    attrs['temp_woeid'] = attrs['woeid']
    Rails.logger.info '>>>>>>>>>>>>> ' + Location.where(:woeid => attrs['woeid']).inspect #STILL NIL
    location = self.create!(attrs)
    location
  end

If the whole thing starts from

Location.create_if_not_existing(woeid)

and it is being NIL (so no other record have the same woeid) WHY IT IS GIVING ME:

ActiveRecord::RecordInvalid (Validation failed: Woeid has already been taken)

Any ideas?

Substantial
  • 6,684
  • 2
  • 31
  • 40
content01
  • 3,115
  • 6
  • 41
  • 61

2 Answers2

2

This is the order of execution during the insertion of an ActiveRecord object:

(-) save
(-) valid
(1) before_validation
(-) validate            *** BOOM
(2) after_validation
(3) before_save         *** too late
(4) before_create
(-) create
(5) after_create
(6) after_save
(7) after_commit

This means the validation is indeed run before your callback is called. To prevent this issue, you can use before_validation instead of before_create

Source: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

Patrick Oscity
  • 53,604
  • 17
  • 144
  • 168
  • temp_woeid is a copy of the actual woeid value. However you can see that the handle_woeid_issue is never called somehow. So how can that be the issue? – content01 May 14 '14 at 00:15
  • 1
    @content01 you were right, although I have another suspicion. Check out my edit. – Patrick Oscity May 14 '14 at 00:29
  • The edit makes sense. However, it seems that `Place` has a `woeid` field too. When they do `gp.attributes.dup`, the `Place` object's `woeid` is in that hash. They never remove it, so it should be present for validation when they `create!`. I'm not sure if the callback is ultimately the problem. – Paul Richter May 14 '14 at 00:34
  • 1
    Using before_validation instead of before_create actually fixed my issue. Thanks a lot! – content01 May 14 '14 at 16:43
0

Use before_save or before_vaidate callback instead of before_create and try

anusha
  • 2,087
  • 19
  • 31