Example:
class Car < ActiveRecord::Base belongs_to :user validates :user, :presence => true ... end
The problem comes when you investigate how validation is made. Each time we save the validated object is got from the database (*). Something simple as:
car = Car.last
car.save
will hit the database checking if user exists.
Solution: build a custom Validator and use it:
class SexyForeignKeyValidator < ActiveModel::EachValidator #http://guides.rubyonrails.org/active_record_validations_callbacks.html#performing-custom-validations def validate_each(record, attribute, value) return if value.present? relation_name = attribute.to_s.gsub(/_id$/,'') unless record.send(relation_name) record.errors.add relation_name.to_sym, :blank end end end
The tricky part is to check for the foreign_key BUT if this is not already set (on create), check for the relation.
This validation run on the foreign key, so we modify the code in the model.
class Car < ActiveRecord::Base belongs_to :user validates :user_id, :sexy_foreign_key => true ... end
One last note. The code for the validator must be included in some path that is automatically loaded ( read this)
Profit!
(*) Note that this is a very particular case, when we check the presence of a relation. Checking for the foreign_key user_id won't work, since on creation, this foreign_key can be null
No comments:
Post a Comment